2014-04-28 11 views
46

Sto cercando di interrogare il mio postgresql db per restituire i risultati in cui una data è in determinati mesi e anni. In altre parole, vorrei tutti i valori per un mese all'anno.Richiesta Postgresql tra intervalli di date

L'unico modo sono stato in grado di farlo finora è come questo:

SELECT user_id 
FROM user_logs 
WHERE login_date BETWEEN '2014-02-01' AND '2014-02-28' 

problema è che devo calcolare la prima data e ultima data prima di interrogare la tabella. C'è un modo più semplice per farlo?

Grazie

+0

è l'intervallo sempre un mese o potrebbe essere, che si avvia forse a 15 e finisce il 7 di seguire mese? – frlan

risposta

89

con date e orari() molte cose diventano più semplici se si utilizza >= start AND < end.

Ad esempio:

SELECT 
    user_id 
FROM 
    user_logs 
WHERE 
     login_date >= '2014-02-01' 
    AND login_date < '2014-03-01' 

In questo caso è comunque necessario calcolare la data di inizio del mese è necessario, ma che dovrebbe essere dritto in avanti in qualsiasi numero di modi.

Anche la data di fine è semplificata; basta aggiungere esattamente un mese. No Giochi per bambini con 28, 30, 31, ecc


Questa struttura ha anche il vantaggio di essere in grado di mantenere l'uso di indici.


Molte persone possono suggerire un modulo come il seguente, ma non uso indici:

WHERE 
     DATEPART('year', login_date) = 2014 
    AND DATEPART('month', login_date) = 2 

Ciò comporta il calcolo delle condizioni per ogni singola riga della tabella (una scansione) e non utilizzare l'indice per trovare l'intervallo di righe che corrisponderanno (un intervallo di ricerca).

+1

Il primo approccio ha bisogno di fare casino con mesi (invece di giorni) per es. '2014-12-01' &' 2015-01-01'. Anche il secondo può essere indicizzato, ma non è banale, lo ammetto: "EXTRACT()" sembra più compatibe. – pozs

-7

Leggere la documentazione.

http://www.postgresql.org/docs/9.1/static/functions-datetime.html

ho usato una query del genere:

WHERE 
(
    date_trunc('day',table1.date_eval) = '2015-02-09' 
) 

o

WHERE(date_trunc('day',table1.date_eval) >='2015-02-09'AND date_trunc('day',table1.date_eval) <'2015-02-09')  

Juanitos Ingenier.

+1

Questo non risponde esattamente alla domanda. La domanda richiede date in base al mese e all'anno. – Ram

3

Da PostreSQL 9.2 Range Types sono supportati. Così si può scrivere questo come:

SELECT user_id 
FROM user_logs 
WHERE '[2014-02-01, 2014-03-01)'::daterange @> login_date 

questo dovrebbe essere più efficiente rispetto al confronto di stringhe

Problemi correlati