Сравнение дат в Oracle SQL

85

Я пытаюсь заставить его отобразить количество сотрудников, которые нанимаются после 20 июня 1994 года, Но я получаю сообщение об ошибке "Недопустимый идентификатор JUN". Пожалуйста, помогите, спасибо!

Select employee_id, count(*)
From Employee
Where to_char(employee_date_hired, 'DD-MON-YY') > 31-DEC-95; 
  • 1
    Также обратите внимание, что вы можете использовать либо > < либо BETWEEN '' AND ''
Теги:

5 ответов

211

31-DEC-95 не является строкой и не является 20-JUN-94. Они - цифры с добавлением дополнительного материала в конце. Это должно быть '31-DEC-95' или '20-JUN-94' - отметить одиночную кавычку '. Это позволит вам выполнить сравнение строк.

Однако вы не выполняете сравнение строк; вы делаете сравнение даты. Вы должны преобразовать строку в дату. Либо используя встроенную функцию TO_DATE(), либо date literal.

TO_DATE()

select employee_id
  from employee
 where employee_date_hired > to_date('31-DEC-95','DD-MON-YY')

Этот метод имеет несколько ненужных ошибок

  • Как отмечалось в комментариях a_horse_with_no_name, DEC, не обязательно означает декабрь. Это зависит от настроек NLS_DATE_LANGUAGE и NLS_DATE_FORMAT, Чтобы убедиться, что ваше сравнение с работой в любой локали вы можете использовать модель формата datetime MM вместо
  • Год '95 неточный. Вы знаете, что вы имеете в виду 1995 год, но что, если это было 50 лет, это 1950 или 2050 год? Всегда лучше быть явным.
select employee_id
  from employee
 where employee_date_hired > to_date('31-12-1995','DD-MM-YYYY')

Литералы даты

Литерал даты является частью стандарта ANSI, что означает, что вам не нужно использовать специальную функцию Oracle. При использовании литерала вы должны указать свою дату в формате YYYY-MM-DD, и вы не можете включить элемент времени.

select employee_id
  from employee
 where employee_date_hired > date '1995-12-31'

Помните, что тип данных даты Oracle включает элемент времени, поэтому дата без временной части эквивалентна 1995-12-31 00:00:00.

Если вы хотите включить временную часть, вам придется использовать литерал timestamp, который принимает формат YYYY-MM-DD HH24:MI:SS[.FF0-9]

select employee_id
  from employee
 where employee_date_hired > timestamp '1995-12-31 12:31:02'

Дополнительная информация

NLS_DATE_LANGUAGE получен из NLS_LANGUAGE и NLS_DATE_FORMAT происходит от NLS_TERRITORY. Они устанавливаются, когда вы изначально создали базу данных, но их можно изменить, изменив файл параметров инициализации - только если это действительно необходимо - или на уровне сеанса с помощью ALTER SESSION. Например:

alter session set nls_date_format = 'DD.MM.YYYY HH24:MI:SS';

Это означает:

  • DD числовой день месяца, 1 - 31
  • MM числовой месяц года, 01 - 12 (январь 01)
  • YYYY 4-значный год - по-моему, это всегда лучше, чем двухзначный год YY, поскольку нет путаницы с тем, о каком веке вы имеете в виду.
  • HH24 час дня, 0 - 23
  • MI минута часа, 0 - 59
  • SS секунда минуты, 0-59

Вы можете узнать свои текущие настройки языка и языка дат, запросив V$NLS_PARAMETERSs и полную гамму допустимых значений, запросив V$NLS_VALID_VALUES.

Дальнейшее чтение


Кстати, если вы хотите count(*), вам нужно сгруппировать по employee_id

select employee_id, count(*)
  from employee
 where employee_date_hired > date '1995-12-31'
 group by employee_id

Это дает вам счет за employee_id.

  • 12
    +1 за использование маски формата в to_date (). Обратите внимание, что это может привести к сбою в других средах из-за разных языковых настроек. DEC не всегда действительный месяц. Обычно лучше использовать цифры вместо имен
  • 0
    @a_horse_with_no_name, спасибо за точку. Я обновил с вашим предложением.
Показать ещё 7 комментариев
3

Вывод

to_char работает по-своему

Итак,

Всегда используйте этот формат ГГГГ-ММ-ДД для сравнения вместо MM-DD-YY или DD-MM-YYYY или любого другого формата

2

из вашего запроса:

Select employee_id, count(*) From Employee 
Where to_char(employee_date_hired, 'DD-MON-YY') > '31-DEC-95' 

Я думаю, что он не отображает число сотрудников, нанятых после 20 июня 1994 года. Если вы хотите показать количество сотрудников, вы можете использовать:

Select count(*) From Employee 
Where to_char(employee_date_hired, 'YYYMMMDDD') > 19940620 

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

employee_date_hired > TO_DATE('20-06-1994', 'DD-MM-YYYY');
or
to_char(employee_date_hired, 'YYYMMMDDD') > 19940620;
2

Вы можете использовать trunc и to_date следующим образом:

select TO_CHAR (g.FECHA, 'DD-MM-YYYY HH24:MI:SS') fecha_salida, g.NUMERO_GUIA, g.BOD_ORIGEN, g.TIPO_GUIA, dg.DOC_NUMERO, dg.* 
from ils_det_guia dg, ils_guia g
where dg.NUMERO_GUIA = g.NUMERO_GUIA and dg.TIPO_GUIA = g.TIPO_GUIA and dg.BOD_ORIGEN = g.BOD_ORIGEN
and dg.LAB_CODIGO = 56 
and trunc(g.FECHA) > to_date('01/02/15','DD/MM/YY')
order by g.FECHA;
-4

Одинарная кавычка должна быть там, так как дата конвертирована в символ.

Select employee_id, count(*)
From Employee
Where to_char(employee_date_hired, 'DD-MON-YY') > '31-DEC-95';
  • 1
    Этот SQL использует неявный формат даты, он не всегда будет работать.
  • 0
    Работает нормально.
Показать ещё 2 комментария

Ещё вопросы

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