Oracle DateTime у пункті Where?


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

-> Взяв більше, ніж out

Будь-яка причина чому?


4
Слід уникати залежних від мови форматів дат. Це може спричинити проблеми в різних системах. Вам слід використовувати 01замість JAN(плюс, звичайно, відповідний формат), щоб переконатися, що ваш код працює без проблем у будь-якій системі.
a_horse_with_no_name

Відповіді:


149

Так: TIME_CREATED містить дату та час . Використовуйте TRUNCдля зменшення часу:

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

ОНОВЛЕННЯ:
Як зазначає Дейв Коста в коментарі нижче, це не дозволить 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, якщо такий існує.
Dave Costa

Дякуємо за розміщення рішення. Це було швидко і легко знайти. Хоча я працював над іншими СУБД, такими як Ingres, MS-SQL, MS-Access та DB2, до мого поточного призначення я ще не працював з Oracle.
Джейсон ТЕПОРТЕН

Чому б не використовувати BETWEEN TO_DATE('26/JAN/2011','dd/mon/yyyy') AND TO_DATE('26/JAN/2011','dd/mon/yyyy') + 1?
ajeh

2
@ajeh: Мені не подобається betweenчерез неоднозначність. Це звучить так, ніби це ексклюзивні межі, коли насправді є інклюзивним. Тому я уникаю цього. Більше того, у цьому конкретному прикладі це не те саме.
Даніель Хілгарт

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

Це тому, що 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')

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 секунду менше, ніж кількість секунд на день.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.