Oracle DB to_date с годом - to_date(2017,'YYYY') неожиданный возврат

При написании нескольких запросов мне нужно было возвращать только те строки, для которых в этом году (2017) был установлен столбец даты, но это не моя проблема. Я знаю, как написать этот запрос несколькими способами, но я натолкнулся на что-то странное и неожиданное для меня., Кто-нибудь может объяснить, почему Oracle db 11.2 ведет себя так?

select sysdate from dual

returns: 
2017/12/05 09:22:27

select to_date(2017,'YYYY'),trunc(sysdate,'YYYY') from dual
returns :
2017/12/01 00:00:00 2017/01/01 00:00:00

select to_date(2017,'YYYY'),trunc(sysdate,'YYYY') from dual
where trunc(sysdate,'YYYY') = to_date(2017,'YYYY')

no rows returned

Почему to_date(2017,'YYYY') возвращается 2017/12/01Вернется ли это 2017/01/01 следующий месяц? Почему это так работает? Я ожидал бы, что это всегда вернется 2017/01/01 независимо от текущего месяца (если часть месяца действительно меняется в зависимости от sysdate).

1 ответ

Решение

В Oracle TO_DATE будет предполагать, что:

  • Если вы не укажете год, то это текущий год;
  • Если вы не укажете месяц, то это текущий месяц;
  • Если вы не укажете день, то это первый день месяца;
  • Если вы не укажете часы, то это полночный час (0);
  • Если вы не укажете минуты, то это будет 0 минут после часа; а также
  • Если вы не укажете секунды, то это будет 0 секунд в минуту.

Вы указываете только год (2017), поэтому он будет:

  • Ноль минут и секунд после полуночи первого дня текущего месяца указанного вами года (2017).

Если вы хотите первый день года, укажите месяц (и, предпочтительно, оставшуюся часть дня):

select to_date( '201701','YYYYMM'),
       trunc(sysdate,'YYYY')
from   dual
where  trunc(sysdate,'YYYY') = to_date( '201701','YYYYMM' )

Или используйте литерал даты:

select DATE '2017-01-01',
       trunc(sysdate,'YYYY')
from   dual
where  trunc(sysdate,'YYYY') = DATE '2017-01-01'
Другие вопросы по тегам