首页 > 解决方案 > 使用 CASE WHEN / LAST_DAY 查询没有给出任何输出

问题描述

在查询下方运行并且没有得到输出。有人可以告诉它有什么问题吗?

Select distinct (table.datex)
from table
where table.datex = 
(
  CASE when extract( day from sysdate) >=19
    then last_day(add_months(sysdate, -1))
    else last_day(add_months(sysdate, -2))
  END
)

样本数据

达泰克斯 ID
21 年 6 月 30 日 一个
21 年 5 月 31 日
21 年 6 月 29 日 C

预期结果

达泰克斯
21 年 6 月 30 日

当我将硬编码的值(由大小写计算)传递给 where 子句时,它工作正常,但是当我应用大小写时,它不起作用。没有错误。没有输出。

标签: sqloracle

解决方案


日期还是日期时间?

甲骨文LAST_DAY并没有像名字所暗示的那样做,文档(https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/LAST_DAY.html#GUID-296C7C02-7FB9-4AAC- 8927-6A79320CE0C6)也无法解释这一点。

与其他几个 DBMS 不同,Oracle 没有日期类型。它只有一个日期时间类型,他们甚至不恰当地调用它DATE。这意味着 Oracle 中的“日期”总是有时间部分。时间部分设置为 00:00:00 的日期可以被视为一天的午夜(即一天的开始)或一整天。

该函数SYSDATE为我们提供了DATE数据类型意义上的日期,而不是真实日期的日期,即它为我们提供了“现在”的日期时间,例如 2021-07-20 14:38:00。ADD_MONTHS更改该日期时间中的月份(有时是年份,有时甚至是日期),即保持时间部分不变。LAST_DAY也将日期部分更改为该月的最后一天,但保持时间部分不变。

因此,您的CASE表达会产生类似TIMESTAMP '2021-07-20 14:38:00'而不是DATE '2021-07-20'预期的结果。

您说您使用案例表达式计算的日期尝试了查询,并且它有效。您是在脑海中还是通过查询来计算结果的一天?如果是后者:您使用的工具可能设置为仅显示日期时间的日期部分并省略时间部分。这可以解释为什么您在检查CASE表达式时只看到 30-JUN-21。

解决方案

将日期时间截断为一整天

Select distinct datex
from mytable 
where (extract(day from sysdate) >=19 and datex = trunc(last_day(add_months(sysdate, -1))))
   or (extract(day from sysdate) < 19 and datex = trunc(last_day(add_months(sysdate, -2))))

TRUNC顺便说一句,您是像我的示例中那样晚申请还是立即在SYSDATE(with ) 上申请都没有关系TRUNC(SYSDATE)。唯一的目的是在表达式中的某个点去掉时间部分。


推荐阅读