案例表达和日期

时间:2018-01-05 17:02:40

标签: sql oracle

我有以下案例表达。

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的结果?

2 个答案:

答案 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