ADD_MONTHS() 如果第二个参数是小数会怎么样?

Oracle ADD_MONTHS 函数详解
本文通过实例详细解析了Oracle数据库中ADD_MONTHS函数的行为特点,特别是对于非整数参数的处理方式,并指出了可能因此导致的日期计算误差。
    我们经常使用ADD_MONTHS()函数来获取一个日期的几个月之后的日期,例如,我们希望得到两个月之后的日期(2013年04月05日):

ChenZw> alter session set nls_date_format = 'yyyy-mm-dd';
会话已更改。
已用时间:  00: 00: 00.00
ChenZw> select add_months(to_date('20130405','yyyymmdd'),2) from dual;
ADD_MONTHS
----------
2013-06-05
已选择 1 行。
已用时间:  00: 00: 00.00

    上面的例子中,我们得到了2013年04月05日后面第二个月的该日期,也就是2013年06月05日,这个是符合我们期望的日期。

但是这里有一个问题,如果我想得到,该日期(2013年04月05日)之后的1.2个月的日期呢?让我们看一下:

ChenZw> select add_months(to_date('20130405','yyyymmdd'),1.2) from dual;
ADD_MONTHS
----------
2013-05-05
已选择 1 行。
已用时间:  00: 00: 00.00

    咦? 这个答案好像不是我想要的,我希望的应该是1.2个月之后的啊!能不能不要这么不严谨!你应该是给我四舍五入了吧?那就告诉我1.9999999999999个月的今天是几号吧!

ChenZw> select add_months(to_date('20130405','yyyymmdd'),1.9999999999999) from dual;
ADD_MONTHS
----------
2013-05-05
已选择 1 行。
已用时间:  00: 00: 00.00

    看到这个答案,我有点无语哽咽了,幸亏没有在工作中使用啊,否则我就悲剧了,日期很有可能就算错了。Oracle,你能不能不这么坑爹。

带着疑惑的心情,去请教Oracle的官方文档:

ADD_MONTHS

Syntax


Purpose

ADD_MONTHS returns the date date plus integer months. A month is defined by the session parameter NLS_CALENDAR. The date argument can be a datetime value or any value that can be implicitly converted to DATEThe integer argument can be an integer or any value that can be implicitly converted to an integer. The return type is always DATE, regardless of the data type of date. If date is the last day of the month or if the resulting month has fewer days than the day component of date, then the result is the last day of the resulting month. Otherwise, the result has the same day component as date.

Examples

The following example returns the month after the hire_date in the sample table employees:

SELECT TO_CHAR(ADD_MONTHS(hire_date, 1), 'DD-MON-YYYY') "Next month"
  FROM employees 
  WHERE last_name = 'Baer';

Next Month
-----------
07-JUL-2002

    现在明白了,原来1.9999999999999是被直接截取成1了,Oracle所谓的implicitly convert是截掉小数点之后的部分。



【--4、去月保费 Execute Immediate 'truncate table jsxs_day_qy1 '; insert into jsxs_day_qy1 select /*+parallel(4) */ level2comcode, level3comcode, riskcode, newchnltype, sum(PREMIUM) PREMIUM, datetype from (select /*+parallel(4) */ b.level2comcode, b.level3comcode, substr(a.RISKCODE, 1, 2) as riskcode, (case when x.newchnltype is null then '00' else x.newchnltype end) newchnltype, (a.PREMIUM * a.EXCHRATE * a.COINSRATE / 100) AS PREMIUM, --原始保费收入 'STATDATE' as datetype FROM WEB_LIST_CMAINORIGIN a, cd_com_all b, ods_cmain x WHERE a.STATDATE between add_months(trunc(sysdate - 1, 'mm'), -12) and add_months(trunc(sysdate - 1), -12) and a.COMCODE = b.comcode and a.policyno = x.policyno(+) UNION ALL select /*+parallel(4) */ d.level2comcode, d.level3comcode, substr(c.RISKCODE, 1, 2) as riskcode, (case when y.newchnltype is null then '00' else y.newchnltype end) newchnltype, (c.CHGPREMIUM * c.EXCHRATE * c.COINSRATE / 100) AS PREMIUM, --批改保费 'STATDATE' as datetype FROM WEB_LIST_PMAIN c, cd_com_all d, ods_pmain y WHERE c.STATDATE between add_months(trunc(sysdate - 1, 'mm'), -12) and add_months(trunc(sysdate - 1), -12) and c.COMCODE = d.comcode and c.endorseno = y.endorseno(+) and c.CHGPREMIUM != 0 union all select /*+parallel(4) */ e.level2comcode, e.level3comcode, substr(f.RISKCODE, 1, 2) as riskcode, (case when m.newchnltype is null then '00' else m.newchnltype end) newchnltype, (f.PREMIUM * f.EXCHRATE * f.COINSRATE / 100) AS PREMIUM, --原始保费收入 'UNDERWRITEENDDATE' as datetype FROM WEB_LIST_CMAINORIGIN f, cd_com_all e, ods_cmain m WHERE f.UNDERWRITEENDDATE between add_months(trunc(sysdate - 1, 'mm'), -12) and add_months(trunc(sysdate - 1), -12) and f.COMCODE = e.comcode and f.policyno = m.policyno(+) UNION ALL select /*+parallel(4) */ h.level2comcode, h.level3comcode, substr(g.RISKCODE, 1, 2) as riskcode, (case when n.newchnltype is null then '00' else n.newchnltype end) newchnltype, (g.CHGPREMIUM * g.EXCHRATE * g.COINSRATE / 100) AS PREMIUM, --批改保费 'UNDERWRITEENDDATE' as datetype FROM WEB_LIST_PMAIN g, cd_com_all h, ods_pmain n WHERE g.STATDATE between add_months(trunc(sysdate - 1, 'mm'), -12) and add_months(trunc(sysdate - 1), -12) and g.COMCODE = h.comcode and g.endorseno = n.endorseno(+) and g.CHGPREMIUM != 0) group by level2comcode, level3comcode, riskcode, newchnltype, datetype; --5、去年保费 Execute Immediate 'truncate table jsxs_day_qn1'; insert into jsxs_day_qn1 select /*+parallel(4) */ level2comcode, level3comcode, riskcode, newchnltype, sum(PREMIUM) PREMIUM, datetype from (select /*+parallel(4) */ b.level2comcode, b.level3comcode, substr(a.RISKCODE, 1, 2) as riskcode, (case when x.newchnltype is null then '00' else x.newchnltype end) newchnltype, (a.PREMIUM * a.EXCHRATE * a.COINSRATE / 100) AS PREMIUM, --原始保费收入 'STATDATE' as datetype FROM WEB_LIST_CMAINORIGIN a, cd_com_all b, ods_cmain x WHERE a.STATDATE between add_months(trunc(sysdate - 1, 'yy'), -12) and add_months(trunc(sysdate - 1), -12) and a.COMCODE = b.comcode and a.policyno = x.policyno(+) UNION ALL select /*+parallel(4) */ d.level2comcode, d.level3comcode, substr(c.RISKCODE, 1, 2) as riskcode, (case when y.newchnltype is null then '00' else y.newchnltype end) newchnltype, (c.CHGPREMIUM * c.EXCHRATE * c.COINSRATE / 100) AS PREMIUM, --批改保费 'STATDATE' as datetype FROM WEB_LIST_PMAIN c, cd_com_all d, ods_pmain y WHERE c.STATDATE between add_months(trunc(sysdate - 1, 'yy'), -12) and add_months(trunc(sysdate - 1), -12) and c.COMCODE = d.comcode and c.endorseno = y.endorseno(+) and c.CHGPREMIUM != 0 union all select /*+parallel(4) */ e.level2comcode, e.level3comcode, substr(f.RISKCODE, 1, 2) as riskcode, (case when m.newchnltype is null then '00' else m.newchnltype end) newchnltype, (f.PREMIUM * f.EXCHRATE * f.COINSRATE / 100) AS PREMIUM, --原始保费收入 'UNDERWRITEENDDATE' as datetype FROM WEB_LIST_CMAINORIGIN f, cd_com_all e, ods_cmain m WHERE f.UNDERWRITEENDDATE between add_months(trunc(sysdate - 1, 'yy'), -12) and add_months(trunc(sysdate - 1), -12) and f.COMCODE = e.comcode and f.policyno = m.policyno(+) UNION ALL select /*+parallel(4) */ h.level2comcode, h.level3comcode, substr(g.RISKCODE, 1, 2) as riskcode, (case when n.newchnltype is null then '00' else n.newchnltype end) newchnltype, (g.CHGPREMIUM * g.EXCHRATE * g.COINSRATE / 100) AS PREMIUM, --批改保费 'UNDERWRITEENDDATE' as datetype FROM WEB_LIST_PMAIN g, cd_com_all h, ods_pmain n WHERE g.STATDATE between add_months(trunc(sysdate - 1, 'yy'), -12) and add_months(trunc(sysdate - 1), -12) and g.COMCODE = h.comcode and g.endorseno = n.endorseno(+) and g.CHGPREMIUM != 0) group by level2comcode, level3comcode, riskcode, newchnltype, datetype; --6、去季度保费 Execute Immediate 'truncate table jsxs_day_qj1 '; insert into jsxs_day_qj1 select /*+parallel(4) */ level2comcode, level3comcode, riskcode, newchnltype, sum(PREMIUM) PREMIUM, datetype from (select /*+parallel(4) */ b.level2comcode, b.level3comcode, substr(a.RISKCODE, 1, 2) as riskcode, (case when x.newchnltype is null then '00' else x.newchnltype end) newchnltype, (a.PREMIUM * a.EXCHRATE * a.COINSRATE / 100) AS PREMIUM, --原始保费收入 'STATDATE' as datetype FROM WEB_LIST_CMAINORIGIN a, cd_com_all b, ods_cmain x WHERE a.STATDATE between add_months(trunc(sysdate - 1, 'q'), -12) and add_months(trunc(sysdate - 1), -12) and a.COMCODE = b.comcode and a.policyno = x.policyno(+) UNION ALL select /*+parallel(4) */ d.level2comcode, d.level3comcode, substr(c.RISKCODE, 1, 2) as riskcode, (case when y.newchnltype is null then '00' else y.newchnltype end) newchnltype, (c.CHGPREMIUM * c.EXCHRATE * c.COINSRATE / 100) AS PREMIUM, --批改保费 'STATDATE' as datetype FROM WEB_LIST_PMAIN c, cd_com_all d, ods_pmain y WHERE c.STATDATE between add_months(trunc(sysdate - 1, 'q'), -12) and add_months(trunc(sysdate - 1), -12) and c.COMCODE = d.comcode and c.endorseno = y.endorseno(+) and c.CHGPREMIUM != 0 union all select /*+parallel(4) */ e.level2comcode, e.level3comcode, substr(f.RISKCODE, 1, 2) as riskcode, (case when m.newchnltype is null then '00' else m.newchnltype end) newchnltype, (f.PREMIUM * f.EXCHRATE * f.COINSRATE / 100) AS PREMIUM, --原始保费收入 'UNDERWRITEENDDATE' as datetype FROM WEB_LIST_CMAINORIGIN f, cd_com_all e, ods_cmain m WHERE f.UNDERWRITEENDDATE between add_months(trunc(sysdate - 1, 'q'), -12) and add_months(trunc(sysdate - 1), -12) and f.COMCODE = e.comcode and f.policyno = m.policyno(+) UNION ALL select /*+parallel(4) */ h.level2comcode, h.level3comcode, substr(g.RISKCODE, 1, 2) as riskcode, (case when n.newchnltype is null then '00' else n.newchnltype end) newchnltype, (g.CHGPREMIUM * g.EXCHRATE * g.COINSRATE / 100) AS PREMIUM, --批改保费 'UNDERWRITEENDDATE' as datetype FROM WEB_LIST_PMAIN g, cd_com_all h, ods_pmain n WHERE g.STATDATE between add_months(trunc(sysdate - 1, 'q'), -12) and add_months(trunc(sysdate - 1), -12) and g.COMCODE = h.comcode and g.endorseno = n.endorseno(+) and g.CHGPREMIUM != 0) group by level2comcode, level3comcode, riskcode, newchnltype, datetype; --7、当季保费 Execute Immediate 'truncate table jsxs_day_dj1 '; insert into jsxs_day_dj1 select /*+parallel(4) */ level2comcode, level3comcode, riskcode, newchnltype, sum(PREMIUM) PREMIUM, datetype from (select /*+parallel(4) */ b.level2comcode, b.level3comcode, substr(a.RISKCODE, 1, 2) as riskcode, (case when x.newchnltype is null then '00' else x.newchnltype end) newchnltype, (a.PREMIUM * a.EXCHRATE * a.COINSRATE / 100) AS PREMIUM, --原始保费收入 'STATDATE' as datetype FROM WEB_LIST_CMAINORIGIN a, cd_com_all b, ods_cmain x WHERE a.STATDATE between trunc(trunc(sysdate - 1), 'q') and trunc(sysdate - 1) and a.COMCODE = b.comcode and a.policyno = x.policyno(+) UNION ALL select /*+parallel(4) */ d.level2comcode, d.level3comcode, substr(c.RISKCODE, 1, 2) as riskcode, (case when y.newchnltype is null then '00' else y.newchnltype end) newchnltype, (c.CHGPREMIUM * c.EXCHRATE * c.COINSRATE / 100) AS PREMIUM, --批改保费 'STATDATE' as datetype FROM WEB_LIST_PMAIN c, cd_com_all d, ods_pmain y WHERE c.STATDATE between trunc(trunc(sysdate - 1), 'q') and trunc(sysdate - 1) and c.COMCODE = d.comcode and c.endorseno = y.endorseno(+) and c.CHGPREMIUM != 0 union all select /*+parallel(4) */ e.level2comcode, e.level3comcode, substr(f.RISKCODE, 1, 2) as riskcode, (case when m.newchnltype is null then '00' else m.newchnltype end) newchnltype, (f.PREMIUM * f.EXCHRATE * f.COINSRATE / 100) AS PREMIUM, --原始保费收入 'UNDERWRITEENDDATE' as datetype FROM WEB_LIST_CMAINORIGIN f, cd_com_all e, ods_cmain m WHERE f.UNDERWRITEENDDATE between trunc(trunc(sysdate - 1), 'q') and trunc(sysdate - 1) and f.COMCODE = e.comcode and f.policyno = m.policyno(+) UNION ALL select /*+parallel(4) */ h.level2comcode, h.level3comcode, substr(g.RISKCODE, 1, 2) as riskcode, (case when n.newchnltype is null then '00' else n.newchnltype end) newchnltype, (g.CHGPREMIUM * g.EXCHRATE * g.COINSRATE / 100) AS PREMIUM, --批改保费 'UNDERWRITEENDDATE' as datetype FROM WEB_LIST_PMAIN g, cd_com_all h, ods_pmain n WHERE g.STATDATE between trunc(trunc(sysdate - 1), 'q') and trunc(sysdate - 1) and g.COMCODE = h.comcode and g.endorseno = n.endorseno(+) and g.CHGPREMIUM != 0) group by level2comcode, level3comcode, riskcode, newchnltype, datetype; --8、去年全年保费 Execute Immediate 'truncate table jsxs_day_qqn'; insert into jsxs_day_qqn select /*+parallel(4) */ level2comcode, level3comcode, riskcode, newchnltype, sum(PREMIUM) PREMIUM, datetype from (select /*+parallel(4) */ b.level2comcode, b.level3comcode, substr(a.RISKCODE, 1, 2) as riskcode, (case when x.newchnltype is null then '00' else x.newchnltype end) newchnltype, (a.PREMIUM * a.EXCHRATE * a.COINSRATE / 100) AS PREMIUM, --原始保费收入 'STATDATE' as datetype FROM WEB_LIST_CMAINORIGIN a, cd_com_all b, ods_cmain x WHERE a.STATDATE between add_months(trunc(sysdate - 1, 'yy'), -12) and trunc(sysdate - 1, 'yy') - 1 and a.COMCODE = b.comcode and a.policyno = x.policyno(+) UNION ALL select /*+parallel(4) */ d.level2comcode, d.level3comcode, substr(c.RISKCODE, 1, 2) as riskcode, (case when y.newchnltype is null then '00' else y.newchnltype end) newchnltype, (c.CHGPREMIUM * c.EXCHRATE * c.COINSRATE / 100) AS PREMIUM, --批改保费 'STATDATE' as datetype FROM WEB_LIST_PMAIN c, cd_com_all d, ods_pmain y WHERE c.STATDATE between add_months(trunc(sysdate - 1, 'yy'), -12) and trunc(sysdate - 1, 'yy') - 1 and c.COMCODE = d.comcode and c.endorseno = y.endorseno(+) and c.CHGPREMIUM != 0 union all select /*+parallel(4) */ e.level2comcode, e.level3comcode, substr(f.RISKCODE, 1, 2) as riskcode, (case when m.newchnltype is null then '00' else m.newchnltype end) newchnltype, (f.PREMIUM * f.EXCHRATE * f.COINSRATE / 100) AS PREMIUM, --原始保费收入 'UNDERWRITEENDDATE' as datetype FROM WEB_LIST_CMAINORIGIN f, cd_com_all e, ods_cmain m WHERE f.UNDERWRITEENDDATE between add_months(trunc(sysdate - 1, 'yy'), -12) and trunc(sysdate - 1, 'yy') - 1 and f.COMCODE = e.comcode and f.policyno = m.policyno(+) UNION ALL select /*+parallel(4) */ h.level2comcode, h.level3comcode, substr(g.RISKCODE, 1, 2) as riskcode, (case when n.newchnltype is null then '00' else n.newchnltype end) newchnltype, (g.CHGPREMIUM * g.EXCHRATE * g.COINSRATE / 100) AS PREMIUM, --批改保费 'UNDERWRITEENDDATE' as datetype FROM WEB_LIST_PMAIN g, cd_com_all h, ods_pmain n WHERE g.STATDATE between add_months(trunc(sysdate - 1, 'yy'), -12) and trunc(sysdate - 1, 'yy') - 1 and g.COMCODE = h.comcode and g.endorseno = n.endorseno(+) and g.CHGPREMIUM != 0) group by level2comcode, level3comcode, riskcode, newchnltype, datetype; --9、前年全年保费 Execute Immediate 'truncate table jsxs_day_qiannianquan'; insert into jsxs_day_qiannianquan select /*+parallel(4) */ level2comcode, level3comcode, riskcode, newchnltype, sum(PREMIUM) PREMIUM, datetype from (select /*+parallel(4) */ b.level2comcode, b.level3comcode, substr(a.RISKCODE, 1, 2) as riskcode, (case when x.newchnltype is null then '00' else x.newchnltype end) newchnltype, (a.PREMIUM * a.EXCHRATE * a.COINSRATE / 100) AS PREMIUM, --原始保费收入 'STATDATE' as datetype FROM WEB_LIST_CMAINORIGIN a, cd_com_all b, ods_cmain x WHERE a.STATDATE between add_months(trunc(sysdate - 1, 'yy'), -24) and add_months(trunc(sysdate - 1, 'yy'), -12) - 1 and a.COMCODE = b.comcode and a.policyno = x.policyno(+) UNION ALL select /*+parallel(4) */ d.level2comcode, d.level3comcode, substr(c.RISKCODE, 1, 2) as riskcode, (case when y.newchnltype is null then '00' else y.newchnltype end) newchnltype, (c.CHGPREMIUM * c.EXCHRATE * c.COINSRATE / 100) AS PREMIUM, --批改保费 'STATDATE' as datetype FROM WEB_LIST_PMAIN c, cd_com_all d, ods_pmain y WHERE c.STATDATE between add_months(trunc(sysdate - 1, 'yy'), -24) and add_months(trunc(sysdate - 1, 'yy'), -12) - 1 and c.COMCODE = d.comcode and c.endorseno = y.endorseno(+) and c.CHGPREMIUM != 0 union all select /*+parallel(4) */ e.level2comcode, e.level3comcode, substr(f.RISKCODE, 1, 2) as riskcode, (case when m.newchnltype is null then '00' else m.newchnltype end) newchnltype, (f.PREMIUM * f.EXCHRATE * f.COINSRATE / 100) AS PREMIUM, --原始保费收入 'UNDERWRITEENDDATE' as datetype FROM WEB_LIST_CMAINORIGIN f, cd_com_all e, ods_cmain m WHERE f.UNDERWRITEENDDATE between add_months(trunc(sysdate - 1, 'yy'), -24) and add_months(trunc(sysdate - 1, 'yy'), -12) - 1 and f.COMCODE = e.comcode and f.policyno = m.policyno(+) UNION ALL select /*+parallel(4) */ h.level2comcode, h.level3comcode, substr(g.RISKCODE, 1, 2) as riskcode, (case when n.newchnltype is null then '00' else n.newchnltype end) newchnltype, (g.CHGPREMIUM * g.EXCHRATE * g.COINSRATE / 100) AS PREMIUM, --批改保费 'UNDERWRITEENDDATE' as datetype FROM WEB_LIST_PMAIN g, cd_com_all h, ods_pmain n WHERE g.STATDATE between add_months(trunc(sysdate - 1, 'yy'), -24) and add_months(trunc(sysdate - 1, 'yy'), -12) - 1 and g.COMCODE = h.comcode and g.endorseno = n.endorseno(+) and g.CHGPREMIUM != 0) group by level2comcode, level3comcode, riskcode, newchnltype, datetype;】改为高斯DB
最新发布
08-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值