2016-08-10 40 views
0

私の質問は私の問題に固有であるため、まずシナリオを説明しようとします。私は、SQLクエリを記述する必要があります。以下は、シナリオです:TABLE1ため個々の日付値の日付範囲のSqlクエリ

表の列:

effective_date 
expire_date 
amount_value 
state_id 
amount_entry_type 

ケース1、入力値:

input_date 

私はSQLクエリ、次の使用してそれを達成した:
サンプルクエリ:

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

私の質問:
今では日付範囲があり、日付範囲の間のすべての日付について上記を達成したいと考えています。

入力は2値:

input_start_date 
input_end_date 

予想される出力:

amount_value grouped by states where input_date between effective and expire_date for input_date between input_start_date and input_end_dateの合計を検索します。

ので、クエリは、日付範囲2016-07-072016-07-08のための次のサンプルの結果を与える:

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

私は結果を照会し、処理するためのデータベースとDjangoとしてはpostgresを使用しています。
オプション:

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 

どちらも上記のソリューションは、私は、単一のSQLクエリを使用してそれを達成することができれば、私は思っていたので、パフォーマンスの問題がある可能性があります。

答えて

1

実際には、generate_series() set-returning-functionを使用して日のリストを作成することで、単一のクエリでこれを行うことができます。すべての日付に状態に対応する行があることが確かな場合は、通常のJOINを使用できます。それ以外の場合はLEFT JOINを以下のように使用します。

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;