Where Date子句中的Oracle DateTime?

san*_*084 76 sql oracle time date-arithmetic

我有这样的sql:

SELECT EMP_NAME, DEPT
FROM EMPLOYEE
WHERE TIME_CREATED >= TO_DATE('26/JAN/2011','dd/mon/yyyy')
Run Code Online (Sandbox Code Playgroud)

- >返回10行,TIME_CREATED = '26 -JAN-2011'

现在,当我这样做时,我没有得到任何行,

SELECT EMP_NAME, DEPT
    FROM EMPLOYEE
    WHERE TIME_CREATED = TO_DATE('26/JAN/2011','dd/mon/yyyy')
Run Code Online (Sandbox Code Playgroud)

- >拿出比大更多的东西

有什么理由吗?

Dan*_*rth 137

是:TIME_CREATED包含日期和时间.使用TRUNC剥离时间:

SELECT EMP_NAME, DEPT
FROM EMPLOYEE
WHERE TRUNC(TIME_CREATED) = TO_DATE('26/JAN/2011','dd/mon/yyyy')
Run Code Online (Sandbox Code Playgroud)

更新:
正如Dave Costa在下面的评论中指出的那样,这将阻止Oracle使用列的索引(TIME_CREATED如果存在).没有这个问题的另一种方法是:

SELECT EMP_NAME, DEPT
FROM EMPLOYEE
WHERE TIME_CREATED >= TO_DATE('26/JAN/2011','dd/mon/yyyy') 
      AND TIME_CREATED < TO_DATE('26/JAN/2011','dd/mon/yyyy') + 1
Run Code Online (Sandbox Code Playgroud)

  • 请注意,此方法将阻止在TIME_CREATED上使用索引(如果存在). (13认同)
  • @ajeh:由于模棱两可,我不喜欢介于两者之间。听起来好像是排他性的,而实际上是包含性的。这就是为什么我避免这样做。此外,在这个具体示例中,情况会有所不同。 (2认同)

小智 23

您还可以使用以下内容在查询中包含TIME部分:

SELECT EMP_NAME
     , DEPT
  FROM EMPLOYEE 
 WHERE TIME_CREATED >= TO_DATE('26/JAN/2011 00:00:00', 'dd/mon/yyyy HH24:MI:SS');
Run Code Online (Sandbox Code Playgroud)


a_h*_*ame 7

这是因为DATEOracle中的列也包含时间部分.to_date()函数的结果是时间设置为的日期,00:00:00因此它可能与表中的任何行都不匹配.

你应该使用:

SELECT EMP_NAME, DEPT
FROM EMPLOYEE
WHERE trunc(TIME_CREATED) = TO_DATE('26/JAN/2011','dd/mon/yyyy')
Run Code Online (Sandbox Code Playgroud)


Bas*_*Roy 5

正如上面其他人所评论的那样,使用TRUNC将阻止使用索引(如果TIME_CREATED上有索引)。为了避免该问题,可以将查询结构为

SELECT EMP_NAME, DEPT
FROM EMPLOYEE
WHERE TIME_CREATED BETWEEN TO_DATE('26/JAN/2011','dd/mon/yyyy') 
            AND TO_DATE('26/JAN/2011','dd/mon/yyyy') + INTERVAL '86399' second;
Run Code Online (Sandbox Code Playgroud)

86399比一天中的秒数少1秒。


Mat*_*ius 5

您也可以这样做:

SELECT EMP_NAME, DEPT
FROM EMPLOYEE
WHERE TRUNC(TIME_CREATED) = DATE '2011-01-26'
Run Code Online (Sandbox Code Playgroud)