今天做一個(gè)數(shù)據(jù)維護(hù)的功能,其中一個(gè)要求是刪除六個(gè)月以前的數(shù)據(jù)。
初步思路:判斷兩個(gè)時(shí)間相差的月份,然后一頓google,沒(méi)發(fā)現(xiàn)有實(shí)現(xiàn)此功能的函數(shù)。
進(jìn)化為:判斷相差的年數(shù),在判斷月數(shù)。弄了汗流浹背,終于完成了。
整想松口氣,突然發(fā)現(xiàn)。。。一個(gè)思路害死人啊。我怎么沒(méi)想到y(tǒng)ear*12呢。
http://blog.csdn.net/gaotianle/archive/2007/10/18/1830304.aspx
問(wèn)題
求兩個(gè)日期之間相差的月數(shù)或年數(shù)。例如,求第一個(gè)員工和最后一個(gè)員工聘用之間相差的月份數(shù),以及這些月折合的年數(shù)。
解決方案
由于一年有12個(gè)月,因此,獲得兩個(gè)日期之間的月份數(shù)之后,再除以12,就能得到年數(shù)。在有了相應(yīng)的解決方案 后,可以根據(jù)此年數(shù)的不同用途對(duì)結(jié)果進(jìn)行舍/入。例如,表EMP中的第一個(gè)HIREDATE(聘用日期)是“17-DEC-1980”,最后一個(gè) HIREDATE是“12-JAN-1983”。如果對(duì)年進(jìn)行減法運(yùn)算(1983減去1980),結(jié)果是3年。然而,月份差大約為25(兩年多一點(diǎn)兒)。 所以應(yīng)該修改解決方案。下列的解決方案返回的結(jié)果是25個(gè)月及2年。
DB2和MySQL
使用函數(shù)YEAR和MONTH為給定日期返回4位數(shù)的年份和兩位數(shù)的月份:
1 select mnth, mnth/12
2 from (
3 select (year(max_hd) - year(min_hd))*12 +
4 (month(max_hd) - month(min_hd)) as mnth
5 from (
6 select min(hiredate) as min_hd, max(hiredate) as max_hd
7 from emp
8 ) x
9 ) y
Oracle
使用函數(shù)MONTHS_BETWEEN,將得到兩個(gè)日期之間相差的月數(shù)(要得到相差年數(shù),只需除以12即可):
1 select months_between(max_hd,min_hd),
2 months_between(max_hd,min_hd)/12
3 from (
4 select min(hiredate) min_hd, max(hiredate) max_hd
5 from emp
6 ) x
PostgreSQL
使用函數(shù)EXTRACT,為給定日期返回4位數(shù)的年和兩位數(shù)的月:
1 select mnth, mnth/12
2 from (
3 select ( extract(year from max_hd) -
4 extract(year from min_hd) ) * 12
5 +
6 ( extract(month from max_hd) -
7 extract(month from min_hd) ) as mnth
8 from (
9 select min(hiredate) as min_hd, max(hiredate) as max_hd
10 from emp
11 ) x
12 ) y
SQL Server
使用函數(shù)DATEDIFF,得到兩個(gè)日期之間相差的月數(shù)(要得到相差年數(shù),只需除以12):
1 select datediff(month,min_hd,max_hd),
2 datediff(month,min_hd,max_hd)/12
3 from (
4 select min(hiredate) min_hd, max(hiredate) max_hd
5 from emp
6 ) x
討論
DB2、MySQL和PostgreSQL
除PostgreSQL解決方案中從MIN_HD和MAX_HD提取了年份、月份的方法不同外,對(duì)于這3個(gè) RDBM,計(jì)算MIN_HD和MAX_HD之間相差年數(shù)和月數(shù)的方法都相同。下面的討論適用于這3種數(shù)據(jù)庫(kù)的解決方案。內(nèi)聯(lián)視圖X返回表EMP中第一個(gè) HIREDATE和最后一個(gè)HIREDATE,如下所示:
select min(hiredate) as min_hd,
max(hiredate) as max_hd
from emp
MIN_HD MAX_HD
----------- -----------
17-DEC-1980 12-JAN-1983
要計(jì)算MIN_HD和MAX_HD 之間的月數(shù),只需用年數(shù)差乘以12,然后再加上MIN_HD和MAX_HD之間的月數(shù)之差。如果不知道其中的機(jī)理,可以將這兩個(gè)日期的有關(guān)部分顯示出來(lái)。它們對(duì)年和月部分的數(shù)值如下所示:
select year(max_hd) as max_yr, year(min_hd) as min_yr,
month(max_hd) as max_mon, month(min_hd) as min_mon
from (
select min(hiredate) as min_hd, max(hiredate) as max_hd
from emp
) x
MAX_YR MIN_YR MAX_MON MIN_MON
------ ---------- ---------- ----------
1983 1980 1 12
觀察上面的結(jié)果,會(huì)發(fā)現(xiàn)MIN_HD和MAX_HD之間相差的月數(shù)是(1983-1980)*12 + (1-12)。要得到MIN_HD和MAX_HD之間相差的年數(shù),只需除以12即可,當(dāng)然,還要根據(jù)用途,對(duì)相差年數(shù)進(jìn)行相應(yīng)的舍/入操作。
Oracle和SQL Server
內(nèi)聯(lián)視圖X返回表EMP中第一個(gè)HIREDATE和最后一個(gè)HIREDATE,如下所示:
select min(hiredate) as min_hd, max(hiredate) as max_hd
from emp
MIN_HD MAX_HD
----------- -----------
17-DEC-1980 12-JAN-1983
由Oracle和SQL Server提供的函數(shù)(分別為MONTHS_BETWEEN和DATEDIFF)可以返回兩個(gè)給定日期之間的月份數(shù)。要得到年數(shù),只需除以12即可。
值得紀(jì)念的一天