2013-04-04 7 views
7

Sono uno sviluppatore SQL e trascorro la maggior parte del mio tempo in MSSQL. Sto cercando un modo migliore per filtrare un campo "timestamp senza fuso orario" in un database PostgreSQLPostgreSQL- Filtra un intervallo di date

sto usando:

Where 
DateField >= '2010-01-01' and 
DateField < '2012-01-01' 

Ma dato che io non sono un esperto di sintassi I devo pensare che c'è un modo migliore.

Suggerimenti? Grazie.

+1

cosa c'è di sbagliato in questo, comunque? Potresti usare 'tra 2010-01-01' e 2012-01-01', ma è quasi lo stesso, davvero. C'è un modo migliore di farlo con MSSQL (non l'ho mai usato)? – Andre

+1

@Andre È meglio specificare esplicitamente il formato della data. –

+0

Va bene, è solo in esecuzione a lungo. Mi sono assicurato che esistesse un indice sul campo, ma mi ci è voluto molto più tempo di quanto mi ero abituato. –

risposta

17

La soluzione va bene. Se le date letterali, preferisco, però:

WHERE datefield >= '2010-01-01 00:00:00' 
AND datefield < '2012-01-01 00:00:00' 

Questo esegue esattamente la stessa cosa, ma è più maintenable, perché rende evidente il punto di ogni "data" letterale di essere un timestamp, non è una data . Ad esempio, supponiamo che a volte qualcuno cambia la query al seguente

AND datefield <= '2012-01-01' 

... in attesa (e non) per includere l'intera giornata "2012-01-01" nella query. Con la sintassi successiva, l'intenzione è più chiara e questa confusione viene prevenuta.

Per rendere ancora più chiaro (forse troppo prolisso), si può fare il cast esplicito:

WHERE datefield >= '2010-01-01 00:00:00'::timestamp 
AND datefield < '2012-01-01 00:00:00'::timestamp 

Non vorrei usare to_date() qui per ragioni analoghe (potenziale tipo di dati confusione), né to_timestamp() (si restituisce un timestamptz).

BTW, ho modificato il caso di osservare le pratica raccomandata (parole chiave in maiuscolo, identificatori in minuscolo)

+2

Puoi utilizzare BETWEEN se utilizzerai --il tuo esempio-- '2010-01-01 00:00:00' :: timestamp come data di inizio e '2010-01-01 24:00:00': : timestamp come la fine. – thisfeller

4

Per gli intervalli di data è possibile usare qualcosa come:

WHERE DateField BETWEEN to_date('2010-01-01','YYYY-MM-DD') 
        AND to_date('2010-01-02','YYYY-MM-DD') 

è più breve (non c'è bisogno di ripetere DateField), e ha formato della data esplicita.

per 1 ora/giorno/mese/anno è possibile utilizzare:

WHERE date_trunc('day',DateField) = to_date('2010-01-01','YYYY-MM-DD') 
+0

'between' non è uguale a'> = e <'poiché include entrambe le estremità. –

+2

@ClodoaldoNeto Per i timestamp (come menzionato in questione) la differenza è in un millisecondo. –