Domanda

Ho bisogno di trovare alcuni record creati in una serie di trimestri. Per esempio, io sto cercando tutti i record creati tra il 4 ° trimestre del 2008 e il 1 ° trimestre del 2010. Ho questo nel mio DOVE clausola:

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

ma Oracle dice: ORA-01820: format code cannot appear in date input format. Il Q è un simbolo formato di data valida, quindi non sono sicuro di quello che è successo. E 'questo anche un modo valido per trovare i valori tra quartieri di calendario, o c'è un modo migliore?


Interessante anche, e forse in relazione, se eseguo questo:

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

Il valore visualizzato nel mio IDE è 2009-08-01. Mi sarei aspettato 2009-08-04, dal momento che oggi è 2010-08-04.

Questa:

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

Naturalmente, non riesce.

(Oracle 10g)

È stato utile?

Soluzione

Oracle dice: ORA-01820: format code cannot appear in date input format. Il Q è un simbolo formato di data valida, quindi non sono sicuro di quello che è successo.

Vedere la seconda colonna della tabella 2.15 a http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/sql_elements004.htm#i34948 . Non tutti gli elementi di formato sono consentiti durante la conversione in date, timestamp, ecc.

mi raccomando contro l'uso tra i controlli per intervallo di date. La gente spesso mancherà valori entro il giorno finale che l'aspettano di essere inclusi. Quindi mi sento di tradurre:

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

Per

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.

Altri suggerimenti

Qualcuno ha chiesto la stessa domanda su OTN: http: // forum .oracle.com / forum / thread.jspa? threadID = 1081398 & Tinizio = 255

Il nocciolo della questione è che si può non specificare "Q" nella funzione TO_DATE.

Dato che si sta già specificare una parte della data, perché non fornire il intero Data? Mente anche che to_date('2010 1','YYYY Q') darebbe 1 gennaio 2010 quando si vuole veramente 31 MARZO 2010 ... in un secondo a mezzanotte.

Poiché la relazione tra quarti di mesi è uno-a-molti, non ha senso fare TO_DATE ( '2008 1', 'aaaa q'); quale data deve essere restituito? Il primo del trimestre, la fine del trimestre, ...? (Al contrario, la conversione di una data ad un quarto -. Come TO_CHAR (SYSDATE, 'aaaa q') senso perché una data specifica esiste solo in un quarto)

Quindi, se si vuole una query che cerca una data che cade tra due trimestri, si dovrà "rolll il proprio" (indicando esplicitamente le date di inizio / fine di un trimestre.)

Come nota a margine, nel caso qualcuno sta prendendo in considerazione non usare TO_DATE prega di non utilizzare le cose come: DOVE date_value TRA 'data string1' e 'data stringa2' senza la funzione TO_DATE. Assume un formato predefinito di data e in certe situazioni può evitare indici potenzialmente utili complessivamente.

Di seguito è un esempio in cui la stessa query può avere un risultato diverso.

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

(Si noti che nel secondo caso si restituisce alcun errore. Esso assume che 10 gen 0001 e testi 10th, 0031).

Penso che il modo migliore è quello basta inserire la data di inizio e di fine quarto trimestre senza nemmeno preoccuparsi con to_date. Penso che se si utilizza

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

per esempio, allora non (in Oracle credo) necessità to_date e non è molto più difficile che la digitazione del numero trimestre

Per calcolare in Oracle il primo giorno di un trimestre e l'ultimo giorno di un quarto dal anno e trimestre: Io uso il fatto

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top