Oracle DateTime在哪里子句?


84

我有这样的SQL:

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

->这将返回10行,并且TIME_CREATED = '26 -JAN-2011'

现在,当我这样做时,我什么也没有回来

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

->采取大于大于

有什么原因吗?


4
您应避免使用依赖于语言的日期格式。这可能会在不同的系统上引起麻烦。您应该使用01而不是JAN(当然还要加上适当的格式)来确保您的代码在任何系统上都能正常运行。
a_horse_with_no_name

Answers:


149

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

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

更新:
正如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

14
请注意,如果存在索引,此方法将阻止在TIME_CREATED上使用索引。
戴夫·科斯塔

感谢您发布解决方案。它很快又很容易找到。当我从事Ingres,MS-SQL,MS-Access和DB2等其他DBMS的工作时,在我当前的工作之前,我还没有与Oracle合作。
杰森·特普顿

为什么不使用BETWEEN TO_DATE('26/JAN/2011','dd/mon/yyyy') AND TO_DATE('26/JAN/2011','dd/mon/yyyy') + 1
ajeh 2013年

2
@ajeh:between由于模棱两可,我不喜欢。听起来好像是排他性的,而实际上却是包括性的。这就是为什么我避免这样做。此外,在这个具体示例中,情况会有所不同。
Daniel Hilgarth

28

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

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


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')

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;

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.