Pregunta

Estoy tratando de usar un formato Año-Semana en Oracle SQL para devolver resultados solo de un rango de Semanas-Año.

Esto es lo que estoy intentando

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

pero dispara este error.

ORA-01820: el código de formato no puede aparecer en el formato de entrada de fecha pero falla en ORA

¿Alguna sugerencia sobre lo que puedo usar?

Gracias amablemente,

Thomas

¿Fue útil?

Solución

Puede darle la vuelta y hacer una comparación de cadenas.

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

Supongo que tiene sentido que to_date () no funcione con IW, ya que el inicio de la semana es algo ambiguo: algunos locales comienzan la semana el domingo, otros el lunes, etc. Generando una semana truncada del año, a diferencia de un día, mes o año truncado, sería difícil.

edit:

Estoy de acuerdo en que el tipo natural debería ser suficiente, pero me tienes pensando. ¿Cómo compararía una fecha determinada y una cadena con formato AAAA-IW? Le di una puñalada. Este intento podría convertirse en una función que tome una fecha y un varchar formateado AAAA-IW, pero necesitaría reemplazar las cadenas codificadas y las llamadas a la función to_date (), y realizar una limpieza.
Devuelve un -1 si la fecha de aprobación es anterior al año / semana del año, 0 si la fecha se encuentra dentro de la semana especificada y 1 si es posterior. Funciona en la semana ISO del año, al igual que el token de formato '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

Otros consejos

¿Qué tal

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

y para rangos

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

El rango utilizará comparaciones de cadenas, que funciona bien si los números más pequeños están rellenados con ceros:  " 2009-08 " y no "2009-8". Pero el formato 'IW' hace este relleno.

Prefiero crear una tabla por semanas para cada año que coincida con la comprensión local de mis dominios, pero solo soy yo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top