Oracle DateTime в пункте, где? - PullRequest
70 голосов
/ 19 июля 2011

У меня есть 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')

-> Взял больше, чем

Есть причина почему?

Ответы [ 5 ]

128 голосов
/ 19 июля 2011

Да: TIME_CREATED содержит дату и время . Используйте TRUNC, чтобы убрать время:

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

UPDATE:
Как указывает Дейв Коста в комментарии ниже, это не позволит 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
22 голосов
/ 20 июля 2011

Вы также можете использовать следующее, чтобы включить часть ВРЕМЯ в ваш запрос:

SELECT EMP_NAME
     , DEPT
  FROM EMPLOYEE 
 WHERE TIME_CREATED >= TO_DATE('26/JAN/2011 00:00:00', 'dd/mon/yyyy HH24:MI:SS');
6 голосов
/ 19 июля 2011

Это связано с тем, что столбец DATE в Oracle также содержит часть времени. Результатом функции to_date() является дата со временем, установленным на 00:00:00, и поэтому она, вероятно, не соответствует ни одной строке в таблице.

Вы должны использовать:

SELECT EMP_NAME, DEPT
FROM EMPLOYEE
WHERE trunc(TIME_CREATED) = TO_DATE('26/JAN/2011','dd/mon/yyyy')
4 голосов
/ 17 мая 2016

Вы также можете сделать:

SELECT EMP_NAME, DEPT
FROM EMPLOYEE
WHERE TRUNC(TIME_CREATED) = DATE '2011-01-26'
4 голосов
/ 19 июля 2011

Как уже отмечали другие люди, использование 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 секунду меньше количества секунд в дне.

...