【问题标题】:oracle sql date comparison doesn't work as expectedoracle sql日期比较没有按预期工作
【发布时间】:2013-01-31 07:41:51
【问题描述】:

我有一个带有“insert_date”列的表 X。此列是 od 类型 DATE 并且所有记录仅包含一个值:“17-JAN-13”。我希望以下查询根本不返回任何结果:

SELECT insert_date
FROM X
  WHERE ("X"."INSERT_DATE" IS NOT NULL
  AND NOT (("X"."INSERT_DATE" = to_date('2013-01-17', 'yyyy-mm-dd')
  )))

但我得到的是许多“17-JAN-13”记录。 我的查询有什么问题?

【问题讨论】:

    标签: sql oracle select oracle-sqldeveloper


    【解决方案1】:

    Oracle DATE 列也包含时间(尽管它们的名称)。您现有的行的时间可能与 00:00:00 不同(“分配”给您使用 to_date() 函数创建的日期)。

    您需要使用trunc()“删除”列的时间部分

    AND NOT (trunc(X.INSERT_DATE) = to_date('2013-01-17', 'yyyy-mm-dd'))
    

    虽然我更喜欢使用 <> 而不是 NOT 运算符:

    AND (trunc(X.INSERT_DATE) <> to_date('2013-01-17', 'yyyy-mm-dd'))
    

    (但这只是个人的偏好。我认为这使条件更易于阅读)。

    所以你的完整陈述是:

    SELECT insert_date
    FROM X
      WHERE trunc(X.INSERT_DATE) <> to_date('2013-01-17', 'yyyy-mm-dd')
    

    【讨论】:

    • 如何提取时间部分来查看里面的内容,而不是 00:00:00?
    • @mnowotka 使用带有合适格式掩码的to_char() 或更改 SQL 客户端的显示设置
    • 虽然trunc()会影响索引的使用;我更喜欢(X.INSERT_DATE &lt; to_date('2013-01-17', 'yyyy-mm-dd') or X.INSERT_DATE &gt;= to_date('2013-01-18', 'yyyy-mm-dd')),但它变得有点乱......
    • @AlexPoole:您始终可以在 trunc(INSERT_DATE) 上定义一个索引,然后使用该索引(只要它充分“减少”返回的行数)
    • 是的,如果这个讨论可能有点先进(并且仍然是一个“影响”)。不知何故,教人们一个有副作用的模型感觉有点尴尬。我猜也是个人喜好 *8-)
    【解决方案2】:

    您可以在比较时截断时间部分,或者仅提取所需的部分,即DD-MON-YYYYlike

    SELECT insert_date FROM X 
    WHERE X.INSERT_DATE IS NOT NULL and to_char(x.INSERT_DATE,'DD-MON-YYYY') <> '17-JAN-2013';
    

    【讨论】:

      猜你喜欢
      • 2019-11-27
      • 1970-01-01
      • 1970-01-01
      • 2018-01-21
      • 1970-01-01
      • 2020-03-04
      • 2018-08-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多