- 问题:
- 对日期加减日、月、年。例如,根据员工CLARK的HIREDATE(聘用日期),计算另外6个不同的日期: 聘用CLARK之前及之后的5天;聘用CLARK之前及之后的5个月;聘用CLARK之前及之后的5年。例如,聘用CLARK的日期为“09-JUN- 1981”,要求返回如下结果集:
- HD_MINUS_5D HD_PLUS_5D HD_MINUS_5M HD_PLUS_5M HD_MINUS_5Y HD_PLUS_5Y
- ----------- ----------- ----------- ----------- ----------- -----------
- 04-JUN-1981 14-JUN-1981 09-JAN-1981 09-NOV-1981 09-JUN-1976 09-JUN-1986
- 12-NOV-1981 22-NOV-1981 17-JUN-1981 17-APR-1982 17-NOV-1976 17-NOV-1986
- 18-JAN-1982 28-JAN-1982 23-AUG-1981 23-JUN-1982 23-JAN-1977 23-JAN-1987
- 解决方案
- DB2对日期值,允许进行标准的加、减操作,但是,如果对日期进行加减操作,后面一定要给出它所表示的时间单位:
- select hiredate -5 day as hd_minus_5D,
- hiredate +5 day as hd_plus_5D,
- hiredate -5 month as hd_minus_5M,
- hiredate +5 month as hd_plus_5M,
- hiredate -5 year as hd_minus_5Y,
- hiredate +5 year as hd_plus_5Y
- from emp
- where deptno = 10
- Oracle对天数采用标准加减,而使用ADD_MONTHS 函数加减月数和年数:
- select hiredate-5 as hd_minus_5D,
- hiredate+5 as hd_plus_5D,
- add_months(hiredate,-5) as hd_minus_5M,
- add_months(hiredate,5) as hd_plus_5M,
- add_months(hiredate,-5*12) as hd_minus_5Y,
- add_months(hiredate,5*12) as hd_plus_5Y
- from emp
- where deptno = 10
- PostgreSQL同时使用标准加减与INTERVAL关键字,INTERVAL指定时间单位。在指定INTERVAL值时,需要用单引号:
- select hiredate - interval '5 day' as hd_minus_5D,
- hiredate + interval '5 day' as hd_plus_5D,
- hiredate - interval '5 month' as hd_minus_5M,
- hiredate + interval '5 month' as hd_plus_5M,
- hiredate - interval '5 year' as hd_minus_5Y,
- hiredate + interval '5 year' as hd_plus_5Y
- from emp
- where deptno=10
- MySQL同时使用标准加减与INTERVAL关键字,INTERVAL指定时间单位。它不同于PostgreSQL解决方案,不必在INTERVAL值周围加单引号:
- select hiredate - interval 5 day as hd_minus_5D,
- hiredate + interval 5 day as hd_plus_5D,
- hiredate - interval 5 month as hd_minus_5M,
- hiredate + interval 5 month as hd_plus_5M,
- hiredate - interval 5 year as hd_minus_5Y,
- hiredate + interval 5 year as hd_plus_5Y
- from emp
- where deptno=10
- 另外,也可以使用DATE_ADD函数,如下所示:
- select date_add(hiredate,interval -5 day) as hd_minus_5D,
- date_add(hiredate,interval 5 day) as hd_plus_5D,
- date_add(hiredate,interval -5 month) as hd_minus_5M,
- date_add(hiredate,interval 5 month) as hd_plus_5M,
- date_add(hiredate,interval -5 year) as hd_minus_5Y,
- date_add(hiredate,interval 5 year) as hd_plus_5DY
- from emp
- where deptno=10
- SQL Server使用DATEADD函数,可以对日期进行不同时间单位的加减操作:
- select dateadd(day,-5,hiredate) as hd_minus_5D,
- dateadd(day,5,hiredate) as hd_plus_5D,
- dateadd(month,-5,hiredate) as hd_minus_5M,
- dateadd(month,5,hiredate) as hd_plus_5M,
- dateadd(year,-5,hiredate) as hd_minus_5Y,
- dateadd(year,5,hiredate) as hd_plus_5Y
- from emp
- where deptno = 10
- 讨论
- 当进行日期运算时,Oracle解决方案采用整型值表示天数。然而,这种方法只能用来对DATE类型进行运 算。Oracle9i Database引入了TIMESTAMP类型,对这种类型的值应该使用PostgreSQL 给出的INTERVAL解决方案;还要注意,不要把TIMESTAMP传递给老版本的日期函数,如ADD_MONTHS,因为这样做会丢失 TIMESTAMP值可能包含的小数部分。
- INTERVAL 关键字以及与它一起使用的字符串符合ISO标准的SQL语法,该标准要求间隔时间单位用单引号括起来。PostgreSQL(以及Oracle9i Database,或更高版本)遵从此标准。但由于MySQL不支持引号,因此在某种程度上它没有遵从此标准。