2016-11-08 2 views
0

У меня есть следующие TABLE.Sample1:Oracle SQL: Сравнение извлеченного Дата в Timestamp

Col1(varchar) | Col2(timestamp) 
--------------------------------------- 
A    | 08-NOV-16 09.59.52.000000000 AM 
B    | 08-NOV-16 10.05.12.000000000 AM 
C    | 09-NOV-16 10.05.12.000000000 AM 

Предположим, что я хочу, чтобы все строки с учетом даты в формате DD MON YYYY.

Вот мой первоначальный запрос:

SELECT * 
    FROM Sample1 
WHERE CAST(Col2 as DATE) = TO_DATE('8 NOV 2016','DD MON YYYY'); 

мне очень интересно, почему этот запрос не работает на равенстве (=), но отлично работает на неравенствах (>, <, <=, >=, <>) , Разве я не сравниваю одни и те же типы данных здесь?

Я закончил использовать функцию TO_CHAR, чтобы сделать эту работу, но она задает вопрос, существует ли более простой или более прямой подход к этому?

SELECT * 
    FROM Sample1 
WHERE TO_CHAR(CAST(Col2 as DATE)) = TO_CHAR(TO_DATE('8 NOV 2016','DD MON YYYY')); 

ответ

1

В Oracle значение DATE все еще имеет время. CAST(Col2 as DATE) не изменит это.

Вы можете использовать trunc() для установки времени часть date (или timestamp) в 00:00:00 и вы не должны сравнивать строки, но даты:

SELECT * 
FROM Sample1 
WHERE trunc(col2) = TO_DATE('8 NOV 2016','DD MON YYYY'); 

Но я настоятельно рекомендую не Используйте формат даты. Это зависит от настроек NLS программы клиента и может завершиться неудачей с различными языковыми настройками.

Я предпочитаю использовать ANSI даты SQL литералов:

SELECT * 
FROM Sample1 
WHERE trunc(col2) = DATE '2016-11-08'; 

В обоих случаях дата будет иметь время 00:00:00, потому что никто не был дан, и, таким образом, сравнение будет работать.

Отметьте, что trunc(col2) не сможет использовать индекс на col2. Если производительность важна, вы должны либо использовать запрос диапазона where col2 >= DATE '2016-11-08' and col2 < DATE '2016-11-09', либо создать индекс на основе функции на trunc(col2).

Смежные вопросы