Pregunta

Tengo que encontrar algunos registros creados en una amplia gama de sectores. Por ejemplo, yo estoy buscando todos los registros creados entre el cuarto trimestre de 2008 y el 1er trimestre de 2010. Tengo esto en mi cláusula WHERE:

...and r.record_create_date between to_date('2008 4','YYYY Q')
                                and to_date('2010 1','YYYY Q')

pero Oracle dice: ORA-01820: format code cannot appear in date input format. El Q es un símbolo formato de fecha válida, así que no estoy seguro de lo que ha pasado. ¿Es esto una forma válida para encontrar valores intermedios cuartos de calandria, o hay una mejor manera?


También es interesante, y posiblemente relacionada, si ejecuto esto:

select to_date('2009','YYYY') from dual;

El valor que aparece en mi IDE es 2009-08-01. Lo que habría esperado 2009-08-04, ya que hoy es 2010-08-04.

Este:

select to_date('2009 1','YYYY Q') from dual;

Por supuesto, no.

(Oracle 10g)

¿Fue útil?

Solución

Oracle dice: ORA-01820: format code cannot appear in date input format. El Q es un símbolo formato de fecha válida, así que no estoy seguro de lo que ha pasado.

Ver la segunda columna de la Tabla 2.15 en http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/sql_elements004.htm#i34948 . No se permiten todos los elementos de formato al convertir a las fechas, marcas de tiempo, etc.

lo recomiendo en contra del uso de cheques entre rango de fechas. La gente a menudo se perderá los valores dentro de la jornada final que la esperan para ser incluidos. Así que yo traduciría:

and r.record_create_date between to_date('2008 4','YYYY Q')
                             and to_date('2010 1','YYYY Q')

a

and to_date('2008-10-01', 'YYYY-MM-DD') <= r.record_create_date 
and record_create_date < to_date('2010-04-01', 'YYYY-MM-DD') -- < beginning of 2Q2010.

Otros consejos

Alguien hizo la misma pregunta en OTN: http: // foros .oracle.com / foros / thread.jspa? threadID = 1081398 y Tinic = 255

El quid de la cuestión es que se puede no especifique "Q" en la función TO_DATE.

Teniendo en cuenta que ya se está especificando una parte de la fecha, ¿por qué no facilita la toda cita? Cuenta también que to_date('2010 1','YYYY Q') le daría 1 ª Ene de 2010, cuando usted realmente quiere 31ra marzo de 2010 ... en un segundo a la media noche.

Dado que la relación entre los trimestres o meses es uno-a-muchos, que no tiene sentido hacer TO_DATE ( '2008 1', 'aaaa q'); qué fecha debe ser devuelto? El primero de la cuarta parte, al final del trimestre, ...? (Por otra parte, la conversión de una fecha para un cuarto -. Como TO_CHAR (SYSDATE, 'aaaa q') tiene sentido porque una fecha específica sólo existe en una cuarta parte)

Por lo tanto, si desea una consulta que busca una fecha en la que se encuentra entre dos cuartas partes, que tendrán que "rolll su propio" (donde se afirma explícitamente las fechas de inicio / final de un trimestre.)

Como nota al margen, por si alguien no está considerando el uso de TO_DATE por favor no usar cosas como: DONDE date_value ENTRE 'fecha de cadena1' y 'fecha string2' sin la función TO_DATE. Supone un formato de fecha por defecto y, en determinadas situaciones puede evitar índices potencialmente útiles en conjunto.

A continuación se muestra un ejemplo en la misma consulta puede tener un resultado diferente.

select sysdate from dual where sysdate between '1-Jan-10' and '31-Dec-10';


SYSDATE
---------
04-AUG-10

SQL> alter session set nls_date_format = 'YYYY-MM-DD';

Session altered.

SQL> select * from dual where sysdate between '1-Jan-10' and '31-Dec-10'; 

no rows selected

(Tenga en cuenta que en el segundo caso se devuelve ningún error. Simplemente asume Jan 10, 0001 y Dec. 10 de 0031).

creo que la mejor forma de hacerlo es simplemente entrada de la fecha de inicio y de fin cuarto trimestre, sin siquiera molestarse con to_date. Creo que si se utiliza

between '1-Jan-10' and '31-Dec-10'

por ejemplo, entonces no lo hace (en Oracle creo) to_date necesidad y no es mucho más difícil que escribir en el número cuarto

Para calcular en Oracle el primer día de un trimestre y el último día de una cuarta parte del año y trimestre: Yo uso el hecho

start_month = -2 + 3 * trimestre

last_month = 3 * trimestre

variable v_year    number

variable v_quarter number

exec :v_year     :=2017

exec :v_quarter:=4

select :v_year    as year,
       :v_quarter as quarter,
       to_date(:v_year||to_char(-2+3*:v_quarter,'fm00'),'yyyymm')        as quarter_start,
       last_day(to_date(:v_year||to_char(3*:v_quarter,'fm00')||'01 23:59:59','yyyymmdd hh24:mi:ss')) as quarter_end
from dual a;


YEAR|QUARTER|QUARTER_START      |QUARTER_END        
2017|      4|2017-10-01 00:00:00|2017-12-31 23:59:59
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top