Oracle DateTime в пункте, где?

56

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

- > Взял больше

По какой причине?

  • 3
    Вы должны избегать зависящих от языка форматов даты. Это может вызвать проблемы в разных системах. Вы должны использовать 01 вместо JAN (плюс, конечно, формат approriate), чтобы убедиться, что ваш код работает без проблем в любой системе.
Теги:
time
date-arithmetic

5 ответов

109
Лучший ответ

Да: 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
  • 13
    Обратите внимание, что этот подход предотвратит использование индекса TIME_CREATED, если он существует.
  • 0
    @Dave: Спасибо за этот указатель. Я обновил свой ответ.
Показать ещё 3 комментария
15

Вы также можете использовать следующее для включения части TIME в свой запрос:

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

Это потому, что столбец 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')
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 секунду меньше, чем количество секунд в день.

0

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню