我有以下案例表达。
SELECT end_dt,
CASE WHEN TO_CHAR(A.END_DT,'MM/DD/YYYY') = '01/01/3000' THEN ''
WHEN TO_CHAR(A.END_DT,'MM/DD/YYYY') > TO_CHAR(SYSDATE,'MM/DD/YYYY') THEN TO_CHAR(SYSDATE,'MM/DD/YYYY')
ELSE TO_CHAR(A.END_DT,'MM/DD/YYYY')
END ENDDATE,
CASE WHEN TO_CHAR(A.END_DT,'YYYYMM') = '300001' THEN ''
WHEN TO_CHAR(A.END_DT,'YYYYMM') > TO_CHAR(SYSDATE,'YYYYMM') THEN TO_CHAR(SYSDATE,'YYYYMM')
ELSE TO_CHAR(A.END_DT,'YYYYMM')
END ENDDATE_YYYYMM,
CASE WHEN TO_CHAR(A.END_DT,'YYYY') = '3000' THEN ''
WHEN TO_CHAR(A.END_DT,'YYYY') > TO_CHAR(SYSDATE,'YYYY') THEN TO_CHAR(SYSDATE,'YYYY')
WHEN TO_CHAR(A.END_DT,'YYYY') > TO_CHAR(SYSDATE,'YYYY') THEN TO_CHAR(SYSDATE,'YYYY')
ELSE TO_CHAR(A.END_DT,'YYYY')
END ENDDATE_YYYY
FROM A
LEFT D ON A.ID = D.ID
WHERE 1=1
ORDER BY 1
输出:
End_dt ENDDATE ENDDATE_YYYYMM ENDDATE_YYYY
12/5/2012 14:33:24 01/05/2018 201212 2012
预期产出:
End_dt ENDDATE ENDDATE_YYYYMM ENDDATE_YYYY
12/5/2012 14:33:24 12/5/2012 201212 2012
为什么我会得到01/05/2018而不是12/5/2012的结果?
答案 0 :(得分:2)
您正在对日期进行字符串比较。停止。对日期进行日期比较。
字符串 '12/5/2012'
大于字符串 '01/05/2018'
,因为1大于0. Oracle正在执行二进制比较。
SQL> select *
2 from dual
3 where '12/5/2012' > '01/05/2018';
D
-
X
停止将所有日期转换为字符串,一切都很好
SQL> select *
2 from dual
3 where date '2018-05-01' > date '2012-05-12';
D
-
X
顺便说一句,空字符串''
相当于Oracle中的NULL。
您的查询应如下所示:
CASE WHEN A.END_DT = date '3000-01-01' then null
WHEN A.END_DT > SYSDATE THEN TO_CHAR(SYSDATE,'MM/DD/YYYY')
ELSE TO_CHAR(A.END_DT,'MM/DD/YYYY')
END ENDDATE,
答案 1 :(得分:1)
不要将日期比较作为字符串。它适用于其他值,因为您的格式正确 - YYYYMMDD(或其中的一部分)。
尝试这个逻辑:
SELECT end_dt,
(CASE WHEN TO_CHAR(A.END_DT, 'MM/DD/YYYY') = '01/01/3000' THEN ''
WHEN A.END_DT > SYSDATE
THEN TO_CHAR(SYSDATE, 'MM/DD/YYYY')
ELSE TO_CHAR(A.END_DT, 'MM/DD/YYYY')
END) as ENDDATE,
(CASE WHEN TO_CHAR(A.END_DT, 'YYYYMM') = '300001' THEN ''
WHEN TO_CHAR(A.END_DT, 'YYYYMM') > TO_CHAR(SYSDATE, 'YYYYMM')
THEN TO_CHAR(SYSDATE,'YYYYMM')
ELSE TO_CHAR(A.END_DT,'YYYYMM')
END) as ENDDATE_YYYYMM,
(CASE WHEN TO_CHAR(A.END_DT, 'YYYY') = '3000' THEN ''
WHEN TO_CHAR(A.END_DT, 'YYYY') > TO_CHAR(SYSDATE, 'YYYY')
THEN TO_CHAR(SYSDATE, 'YYYY')
WHEN TO_CHAR(A.END_DT, 'YYYY') > TO_CHAR(SYSDATE,'YYYY')
THEN TO_CHAR(SYSDATE, 'YYYY')
ELSE TO_CHAR(A.END_DT, 'YYYY')
END) as ENDDATE_YYYY