Oracle Query - 选择end_date(可能为NULL / EMPTY)大于sysdate的行

时间:2016-01-14 09:29:14

标签: sql oracle

我有Oracle表Demo_t,其列end_date的值可能为null。我想选择end_date大于当前日期的所有行。

我在下面写了查询

select * from Demo_t where NVL(End_date,sysdate+3) > sysdate;

毫无疑问,查询给出了预期的结果,但我想确保我没有遗漏某些东西,或者存在任何其他更好的解决方案。它将帮助我更好地理解Oracle数据库。

谢谢,

3 个答案:

答案 0 :(得分:5)

如果End_Date为空,则将其记录在结果中。那是你要的吗? 如果是这样,你可以像

那样写
SELECT *
FROM DEMO_T
WHERE END_DATE > SYSDATE OR END_DATE IS NULL;

如果您不想要,可以尝试

SELECT *
FROM DEMO_T
WHERE END_DATE > SYSDATE;

在您的代码中:

NVL(End_date,sysdate+3)实际上会为表格中的每一行增加sysdate,如果您只需检查End_Date是否为null就不是一个好主意

编辑:正如@Thorsten Kettner所说,查询中只有一个sysdate,因此不会为每一行计算

答案 1 :(得分:1)

你查询没问题。您可以使用它或使用(end_date > sysdate or end_date is null)明确地检查NULL。两者都做同样的事情,而有些人更喜欢前者,有些人更喜欢后者,有些人总是使用DECODE来检查可空列。使用您认为最具可读性的内容并坚持在所有查询中(或在团队中:使用同事使用的内容)。保持一致。

但是,有一种方法可以加快此类查询:使用高修复日期而不是SYSDATE+3,通常类似于DATE'9999-12-31'。然后在此表达式上创建一个函数索引。

create index idx_end_date on demo_t ( nvl(end_date, date'9999-12-31') );

匹配查询:

select * from demo_t where nvl(end_date, date'9999-12-31') > sysdate;

由于索引涵盖所有日期,因此使用它的可能性要高于end_date上的单纯索引。这可以极大地加速查询。

顺便提一下:请注意SYSDATE包含时间部分。如果end_date仅包含日期,那么您可能希望在比较中TRUNC(SYSDATE)

答案 2 :(得分:0)

您应该使用trunc作为日期,否则它会比较时间并可能输出错误。

select *   
  from Demo_t   
 where trunc(nvl(end_date,sysdate+1)) > trunc(sysdate);