【问题标题】:Oracle SQL comparison of DATEs returns wrong resultDATE 的 Oracle SQL 比较返回错误结果
【发布时间】:2015-05-14 08:25:38
【问题描述】:

我在数据库 (DATETIME) 类型中有 REPORTDATE 列。 我只想从 DATETIME 中提取 DATE 值,然后每天执行 COUNT 并添加 WHERE 子句以限制仅晚于某个特定日期的日期。

所以我有这个条款:

SELECT to_char(REPORTDATE, 'DD.MM.YYYY') AS MY, COUNT(*) from INCIDENT
where to_char(REPORTDATE, 'DD.MM.YYYY')>'09.11.2013'

GROUP BY to_char(REPORTDATE, 'DD.MM.YYYY')

它返回我的结果,但我可以注意到错误的结果,例如:30.10.2013 这是错误的结果。

如何解决?

【问题讨论】:

  • to_char(REPORTDATE, 'DD.MM.YYYY')>'09.11.2013'。当您将其转换为 char 时,您希望它如何比较?

标签: sql oracle date select where-clause


【解决方案1】:

WHERE to_char(REPORTDATE, 'DD.MM.YYYY')>'09.11.2013'

您正在比较两个 STRINGS。您需要比较 DATE。正如我在这里的另一个答案中已经说过的那样,您需要将日期保留为 DATE 计算。 TO_CHAR 用于显示,TO_DATE 用于将字符串文字转换为 DATE。

SELECT TO_CHAR(REPORTDATE, 'DD.MM.YYYY'),
  COUNT(*)
FROM TABLE
WHERE REPORTDATE > TO_DATE('09.11.2013', 'DD.MM.YYYY')
GROUP BY TO_CHAR(REPORTDATE, 'DD.MM.YYYY') 

另外,REPORTDATE 是一个 DATE 列,因此它会有 datetime 元素。所以,如果你想在比较时排除时间元素,你需要使用 TRUNC

WHERE TRUNC(REPORTDATE) > TO_DATE('09.11.2013', 'DD.MM.YYYY')

但是,在日期 column 上应用 TRUNC 会抑制该列上的任何常规 index。从性能的角度来看,最好使用日期范围条件

例如,

WHERE REPORTDATE
BETWEEN 
        TO_DATE('09.11.2013', 'DD.MM.YYYY')
AND     
        TO_DATE('09.11.2013', 'DD.MM.YYYY') +1

【讨论】:

  • @Dejan,你不需要把 TRUNC 放在我最后展示的列上。
  • @Lalit Kumar B - 关于您回答的这一部分:“您正在比较两个字符串。您需要比较日期”:我认为值得指出的是 OP 原始查询的原因由于使用字符串比较而不是日期比较,因此 not 工作。这是由于他们进行字符串比较的方式。如果他们使用了 to_char(REPORTDATE, 'YYYY.MM.DD')>'2013.09.11',那么查询就会起作用。
  • @dcp,就像说'a' > 'b'
  • @Latif Kumar B - 不确定我是否理解您的评论。 “a”实际上小于“b”。我的意思是查询没有错,因为他比较的是字符串而不是日期,这就是他比较不正确的字符串的方式。但是,您的回答似乎表明您必须使用日期比较才能使查询正常工作,这是不正确的。
  • @DavidFaber 我现在添加了那部分。
【解决方案2】:

条件to_char(REPORTDATE, 'DD.MM.YYYY')>'09.11.2013' 与字符串比较,所以30.10.201309.11.2013 之后。 您需要比较日期,而不是字符串值,因此您必须将查询更改为以下内容。

SELECT to_char(REPORTDATE, 'DD.MM.YYYY') AS MY, COUNT(1) 
from INCIDENT
where trunc(REPORTDATE)> to_date('09.11.2013', 'DD.MM.YYYY')
GROUP BY to_char(REPORTDATE, 'DD.MM.YYYY')

注意:我对@9​​87654327@ 到count(1) 进行了一些修改,以优化具有相同结果的查询。

【讨论】:

  • COUNT(1) 不提供超过COUNT(*) 的任何内容。
  • COUNT(*) 检查是否有任何列的值不为空。 COUNT(1) 不检查单列。它返回行数,而不是至少一个字段不为空的行数。
  • COUNT(*) check if any of the columns has a value not null - 这个声明的依据是什么?请看这里:stackoverflow.com/questions/1221559/count-vs-count1
  • @DavideLorenzoMARINO Count(*) 和 Count(1) 在所有方面都是相同的。除非你在原始版本中,它曾经有一些不同。过去对此进行过多次讨论。只是谷歌它,看看。大师 Thomas Kyte 的最佳答案在这里 asktom.oracle.com/pls/asktom/…
猜你喜欢
  • 1970-01-01
  • 2015-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多