Oracle函数之间的确切逻辑是什么?
我试过这个查询:
SELECT D1,
D2,
MONTHS_BETWEEN (D1, D2) DIFF,
(D1-D2)/31 MANUAL_CALC1,
(D1-D2)/30 MANUAL_CALC2,
(D1-D2)/29 MANUAL_CALC3,
(D1-D2)/28 MANUAL_CALC4
FROM (SELECT TO_DATE('07-03-2014', 'DD-MM-YYYY') D1,
TO_DATE('04-02-2014', 'DD-MM-YYYY') D2
FROM DUAL);
结果如下:
DIFF:1.09
MANUAL_CALC1:1
MANUAL_CALC2:1.03
MANUAL_CALC3:1.06
MANUAL_CALC4:1.10
我正在将Oracle包转换为Java程序,我需要生成完全相同的结果。但只是这一个功能(months_between)正在破坏党。
答案 0 :(得分:2)
4th of Feb
至4th of March
为1
月..
剩余 3 天到7th of March
..所以3/31
(总是31作为基准)= .09
个月
所以答案总是1+ 0.09 = 1.09
公式如此,
FLOOR(ABS(MONTHS_BETWEEN(D1,D2))) + /* The Actual Month difference, as whole number */
(TO_CHAR(D1,'DD') - TO_CHAR(D2,'DD'))/31 /* Remaining Days / 31)*/
答案 1 :(得分:0)
SELECT
a.dt_base,
a.dt,
a.months,
a.days,
a.mms,
a.my_months,
a.bias,
a.day_part,
a.my_add_months
FROM
(
SELECT
a.dt_base,
a.dt,
a.months,
a.days,
a.mms,
a.my_months,
31 - TO_NUMBER(TO_CHAR(LAST_DAY(ADD_MONTHS(a.dt_base,TRUNC(a.months))),'dd')) bias,
((a.months - TRUNC(a.months)) * 31) day_part,
CASE WHEN TO_CHAR(ADD_MONTHS(a.dt_base,TRUNC(a.months)),'yyyymm') != TO_CHAR((ADD_MONTHS(a.dt_base,TRUNC(a.months)) + ((a.months - TRUNC(a.months)) * 31)),'yyyymm') THEN
ADD_MONTHS(a.dt_base,TRUNC(a.months)) + ((a.months - TRUNC(a.months)) * 31) - (31 - TO_NUMBER(TO_CHAR(LAST_DAY(ADD_MONTHS(a.dt_base,TRUNC(a.months))),'dd')))
ELSE
ADD_MONTHS(a.dt_base,TRUNC(a.months)) + ((a.months - TRUNC(a.months)) * 31)
END my_add_months
FROM
(
SELECT
a.dt_base,
a.dt,
a.months,
a.days,
a.mms,
mms + days / 31 my_months
FROM
(
SELECT
a.dt_base,
a.dt,
a.months,
CASE WHEN TO_CHAR(a.dt_base,'dd') > to_char(a.dt,'dd') THEN
31 - TO_NUMBER(TO_CHAR(a.dt_base,'dd')) + TO_NUMBER(TO_CHAR(a.dt,'dd'))
ELSE
TO_NUMBER(TO_CHAR(a.dt,'dd')) - TO_NUMBER(TO_CHAR(a.dt_base,'dd'))
END days
, CASE WHEN TO_CHAR(a.dt_base,'dd') > TO_CHAR(a.dt,'dd') THEN
( TO_NUMBER(TO_CHAR(a.dt,'yyyy')) * 12 + TO_NUMBER(TO_CHAR(a.dt,'mm')) )
-
( TO_NUMBER(TO_CHAR(a.dt_base,'yyyy')) * 12 + TO_NUMBER(TO_CHAR(a.dt_base,'mm')) )
- 1
ELSE
( TO_NUMBER(TO_CHAR(a.dt,'yyyy')) * 12 + TO_NUMBER(TO_CHAR(a.dt,'mm')) )
-
( TO_NUMBER(TO_CHAR(a.dt_base,'yyyy')) * 12 + TO_NUMBER(TO_CHAR(a.dt_base,'mm')) )
END mms
FROM
(
SELECT
dt_base,
dt,
MONTHS_BETWEEN(dt,dt_base) months
FROM
(
SELECT
TRUNC(sysdate,'dd') dt_base,
TRUNC(sysdate,'dd') + level - 1 dt
FROM dual
CONNECT BY level < 36500
) a
) a
)a
) a
) a
WHERE a.dt != a.my_add_months