私は次のような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')
->「より大きい」を取得しました
なんで?
はい: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
次を使用して、クエリにTIME部分を含めることもできます。
SELECT EMP_NAME
, DEPT
FROM EMPLOYEE
WHERE TIME_CREATED >= TO_DATE('26/JAN/2011 00:00:00', 'dd/mon/yyyy HH24:MI:SS');
これは、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')
他の人が上記でコメントしたように、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日の秒数より1秒短くなります。
次のこともできます。
SELECT EMP_NAME, DEPT
FROM EMPLOYEE
WHERE TRUNC(TIME_CREATED) = DATE '2011-01-26'