2016-11-23 5 views
2

私は、今後6ヶ月間のすべての製品の予測を格納するforecastsテーブルを用意しています。たとえば、11月には12月、1月、2月、3月、4月、5月の予測を作成します。予測テーブルは、テーブルには、製品番号および予測が作成された日付すなわちforecasted_onと予測が予測と一緒にするために作成された月のリストが含まれていポストグルで過去3ヶ月の予測を月ごとに計算する

+----------------+---------------+--------------+----------+ 
| product_number | forecasted_on | forecast_for | quantity | 
+----------------+---------------+--------------+----------+ 
| Prod 1   | 2016-11-01 | 2016-12-01 |  100 | 
| Prod 1   | 2016-11-01 | 2017-01-01 |  200 | 
| Prod 1   | 2016-11-01 | 2017-02-01 |  300 | 
| Prod 1   | 2016-11-01 | 2017-03-01 |  400 | 
| Prod 1   | 2016-11-01 | 2017-04-01 |  500 | 
| Prod 1   | 2016-11-01 | 2017-05-01 |  600 | 
+----------------+---------------+--------------+----------+ 

下図のようになります量。

各月のデータは今後6か月間追加されます。したがって、forecasted_onが1-December-2016の場合、予測は6月まで1月に作成されます。

私は過去3か月間の予測合計がどのように変化したかを示すレポートを作成しようとしています。このようなもの

+------------+----------------+---------------+----------------+ 
|   | 0 months prior | 1 month prior | 2 months prior | 
+------------+----------------+---------------+----------------+ 
| 2016-12-01 |   200 |   150 |   250 | 
| 2017-01-01 |   300 |   250 |   150 | 
| 2017-02-01 |   100 |   150 |   100 | 
+------------+----------------+---------------+----------------+ 

現在、この表を生成するために、多くの繰り返しコードをレールに使用しています。私は、SQLクエリを使用して直接行う簡単な方法があるかどうかを見たいと思っていました。

ご協力いただければ幸いです。

答えて

0

使用PIVOTクエリ:

select forecast_for, 
     sum(case when forecasted_on + interval '1' month = forecast_for 
      then quantity end) q_0, 
     sum(case when forecasted_on + interval '2' month = forecast_for 
      then quantity end) q_1, 
     sum(case when forecasted_on + interval '3' month = forecast_for 
      then quantity end) q_2, 
     sum(case when forecasted_on + interval '4' month = forecast_for 
      then quantity end) q_3, 
     sum(case when forecasted_on + interval '5' month = forecast_for 
      then quantity end) q_4, 
     sum(case when forecasted_on + interval '6' month = forecast_for 
      then quantity end) q_5 
from Table1 
group by forecast_for 
order by 1 
; 

デモ:http://sqlfiddle.com/#!15/30e5e/1

|    forecast_for | q_0 | q_1 | q_2 | q_3 | q_4 | q_5 | 
|----------------------------|--------|--------|--------|--------|--------|--------| 
| December, 01 2016 00:00:00 | 100 | (null) | (null) | (null) | (null) | (null) | 
| January, 01 2017 00:00:00 | (null) | 200 | (null) | (null) | (null) | (null) | 
| February, 01 2017 00:00:00 | (null) | (null) | 300 | (null) | (null) | (null) | 
| March, 01 2017 00:00:00 | (null) | (null) | (null) | 400 | (null) | (null) | 
| April, 01 2017 00:00:00 | (null) | (null) | (null) | (null) | 500 | (null) | 
|  May, 01 2017 00:00:00 | (null) | (null) | (null) | (null) | (null) | 600 | 
0

、これは仕事をしなければならない、(そう何の集約が必要とされない)(product_number, forcast_on, forcasted_for)が一意であると仮定すると:

WITH forecast_dates AS (
    SELECT DISTINCT product_number, forcast_for 
    FROM forecasts 
) 
SELECT 
    fd.forcast_for AS "forecast for", 
    m1.quantity AS "one month prior", 
    m2.quantity AS "two months prior", 
    m3.quantity AS "three months prior" 
FROM forecast_dates fd 
    LEFT JOIN forecasts m1 ON fd.forcast_for = m1.forcast_for AND fd.forcast_for = m1.forcasted_on + INTERVAL '1 month' 
    LEFT JOIN forecasts m2 ON fd.forcast_for = m2.forcast_for AND fd.forcast_for = m2.forcasted_on + INTERVAL '2 month' 
    LEFT JOIN forecasts m3 ON fd.forcast_for = m3.forcast_for AND fd.forcast_for = m3.forcasted_on + INTERVAL '3 month' 
WHERE fd.product_number = 'Prod 1' 
ORDER BY fd.forcast_for; 
関連する問題