SQL возвращает результаты 13 недели 2008 года (не сгруппированы) - PullRequest
2 голосов
/ 24 июня 2009

Я пытаюсь использовать формат Year-Week в Oracle SQL для возврата результатов только из диапазона Year-Weeks.

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

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

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

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

Thomas

Ответы [ 3 ]

5 голосов
/ 24 июня 2009

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

 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? Я сделал удар в это. Эта попытка может быть преобразована в функцию, которая принимает дату и форматированный YYYY-IW varchar, но вам нужно будет заменить жестко закодированные строки и вызовы функций to_date () и выполнить некоторую очистку.
Возвращает -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
0 голосов
/ 24 июня 2009

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

0 голосов
/ 24 июня 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' делает это заполнение.

...