2016-08-10 5 views
0

Meine Frage ist spezifisch für mein Problem, also würde ich versuchen, das Szenario zuerst zu erklären. Ich muss eine SQL-Abfrage schreiben. Im Anschluss wird das Szenario:SQL Query für den Datumsbereich für einzelne Datumswerte

Tabellenspalten für table1:

effective_date 
expire_date 
amount_value 
state_id 
amount_entry_type 

Fall 1, Eingabewerte:

input_date 

Ich habe erreicht es folgende SQL-Abfrage verwenden:
Beispielabfrage:

select state_id, sum(amount) 
from table1 
where state_id=3 and (input_date between effective_date and expiry_date) 
group by state_id; 

Meine Frage:
Jetzt habe ich einen Datumsbereich und ich möchte das oben für alle Termine zwischen Datumsbereich erreichen.

Eingangswerte 2:

input_start_date 
input_end_date 

Erwartete Ausgabe:

die Summe von amount_value grouped by states where input_date between effective and expire_date for input_date between input_start_date and input_end_date finden.

So würde die Abfrage folgendes Beispielergebnis für Datumsbereich 2016-07-07 und 2016-07-08 geben:

state   amount_sum  date 
California 100   2016-07-07 
Florida  200   2016-07-08 

ich Postgres als Datenbank und django zur Abfrage und Verarbeitung des Ergebnisses verwenden.
Optionen:

1. Fetch all the data and process using python. 
2. Loop over given date range and fire the query above as: 

for input_date in date_range(input_start_date, input_end_date): 
    //Execute above query 

Beide oben genannten Lösungen können Performance-Probleme haben, damit ich frage mich, ob ich es mit einzelnen SQL-Abfrage erreichen könnte.

Antwort

1

Sie können dies tatsächlich mit einer einzigen Abfrage tun, mit der generate_series() Set-Rückgabe-Funktion, um die Liste der Tage zu machen. Wenn Sie sicher sind, dass alle Daten entsprechende Zeilen für den Status haben, können Sie einen normalen JOIN verwenden, andernfalls verwenden Sie einen LEFT JOIN wie unten.

SELECT state_id, sum(amount), dt AS "date" 
FROM generate_series(input_start_date, input_end_date, '1 day') dates(dt) 
LEFT JOIN table1 ON state_id = 3 AND (dt BETWEEN effective_date AND expiry_date) 
GROUP BY state_id, dt; 
Verwandte Themen