SQL для возврата результатов за неделю 13 2008 года (не сгруппированы)

Я пытаюсь использовать формат «Год-Неделя» в оракуле SQL, чтобы возвращать результаты только из диапазона «Год-Недели».

Вот что я пытаюсь

SELECT * FROM widsys.train trn WHERE trn.WID_DATE>=TO_DATE('2008-13', 'YYYY-IW') AND trn.WID_DATE<=TO_DATE('2008-15', 'YYYY-IW') ORDER BY trn.wid_date

но выдает эту ошибку.

ORA-01820: код формата не может отображаться в формате ввода даты, но не работает в ORA

Любые предложения о том, что я могу использовать?

Спасибо любезно,

Томас


person Community    schedule 24.06.2009    source источник


Ответы (3)


Вы можете перевернуть его и выполнить сравнение строк.

 SELECT * 
 FROM widsys.train trn 
 WHERE to_char(trn.WID_DATE, 'YYYY-IW') ='2008-13'
 ORDER BY trn.wid_date;

Я полагаю, что имеет смысл, что to_date() не работает с IW, так как начало недели несколько неоднозначно - некоторые локали начинают неделю в воскресенье, другие в понедельник и т. д. Генерация усеченной недели года, в отличие от усеченной день, месяц или год, поэтому было бы трудно.

изменить:

Я согласен, что естественного вида должно быть достаточно, но вы заставили меня задуматься. Как бы вы сравнили заданную дату и отформатированную строку YYYY-IW? Я нанес удар. Эту попытку можно превратить в функцию, которая принимает дату и тип varchar в формате YYYY-IW, но вам потребуется заменить жестко закодированные строки и вызовы функции to_date(), а также выполнить некоторую очистку.
Она возвращает a -1, если переданная дата предшествует году/неделе года, 0, если дата попадает в указанную неделю года, и 1, если она позже. Он работает на неделе года ISO, как и токен формата «IW».

 select (case 
      when input.day < a.startofweek then -1
      when input.day < a.startofweek+7 then 0
      else 1 end)
 from 
 (select 
 -- //first get the iso offset for jan 1, this could be removed if you didn't want iso 
    (select (max(to_number(to_char(to_date('2008','YYYY') + level,'DDD')))) 
     from dual 
     where to_number(to_char(to_date('2008','YYYY')  + level,'IW')) 
      <2 connect by level <= 6) -6
    +
 -- //next get the days in the year to the month in question   
    (select ((to_number(substr('2008-13', 6,2))-1)*7) from dual) startofweek 
     from dual) a, 
 -- //this is generating a test date
  (select to_number(to_char(to_date('2008-07-19', 'YYYYMMDD'), 'DDD')) day 
    from dual) input, 
  dual
person akf    schedule 24.06.2009
comment
Это работает на ура! Спасибо. Но мне также нужно превратить его в недельный диапазон (я отредактировал свой вопрос). Я пробовал ›='2008-13', но я не думаю, что это понятно для строки. - person ; 24.06.2009
comment
Попробуйте, естественный порядок строк должен позволять вам делать такие вещи, как '2008-13' › x › '2008-18' - person Dana the Sane; 24.06.2009

Как насчет

select * from widsys.train trn 
  where to_char(trn.wid_date, 'YYYY-IW') =  ?
  order by trn.wid_date

и для диапазонов

select * from widsys.train trn 
  where to_char(trn.wid_date, 'YYYY-IW') between ? and ?
  order by trn.wid_date

Диапазон будет использовать сравнение строк, которое отлично работает, если меньшие числа дополнены нулями: «2009-08», а не «2009-8». Но формат «IW» делает это заполнение.

person Thilo    schedule 24.06.2009
comment
Спасибо за ответ! Он работал нормально, но возвращал странные результаты, когда я пытался расширить его до диапазона. Я предполагаю, что ›= или ‹= не имеет смысла сравнивать такие строки, как 2009-13? - person ; 24.06.2009
comment
Диапазоны должны работать. Просто убедитесь, что у вас есть отступы с нулем: «2009-08», а не «2009-8». - person Thilo; 24.06.2009

Я предпочитаю создавать таблицу по неделям для каждого года, которая соответствует моему локальному пониманию доменов, но это только я.

person Mark Schultheiss    schedule 24.06.2009
comment
эта таблица нуждается в ежегодном обновлении, не так ли? - person akf; 24.06.2009
comment
Да, но вы могли бы легко сделать это, используя автоматизированную механику, или просто поставить значение на 100 лет — разница в производительности для 520 строк по сравнению с 52 тривиальна. У этого есть дополнительное преимущество в том, что если вы используете недели, определенные клиентом, у вас теперь есть механизм для этого, просто добавьте идентификатор клиента в таблицу для каждого клиента. - person Mark Schultheiss; 25.06.2009