2011-07-19 99 views
56

我有SQL是這樣的:Oracle DateTime在Where子句中?

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

- >接過大於出

有什麼理由?

+3

你應該避免依賴於語言的日期格式。這可能會在不同的系統上造成麻煩。您應該使用'01'而不是'JAN'(加上適當的格式),以確保您的代碼在任何系統上運行時都沒有問題。 –

回答

108

是:TIME_CREATED包含日期和時間。使用TRUNC剝去時間:

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

UPDATE:
戴維科斯塔在下面的評論指出,這將阻止甲骨文從使用列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 
+13

請注意,此方法將阻止在TIME_CREATED上使用索引(如果存在)。 –

+0

@Dave:謝謝你的指針。我更新了我的答案。 –

+0

謝謝發佈解決方案。這是快速和容易找到。 雖然我曾在其他DBMS(如Ingres,MS-SQL,MS-Access和DB2)上工作,但在我當前的任務之前,我還沒有與Oracle一起工作過。 –

6

這是因爲在Oracle中DATE列還包含一個時間的一部分。 to_date()函數的結果是時間設置爲00:00:00的日期,因此它可能不匹配表中的任何行。

你應該使用:

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

正如其他人上述評論,使用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秒。

15

您也可以使用下面的方法包括在查詢中的時間部分:

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

你也可以這樣做:

SELECT EMP_NAME, DEPT 
FROM EMPLOYEE 
WHERE TRUNC(TIME_CREATED) = DATE '2011-01-26'