2017-03-22 10 views
0

したがって、同じコホートは同じ月に製品を使用し始めたグループの集まりです。私はそれから、現時点までの各月の各コホートの総使用量を追跡します。SQLクエリの行に将来の日付のセットリストを追加する

たとえば、最初の「コホート月」は2012年1月です。その後、3月17日(今月)の1月12日、2月12日、3月12日...となります。 1つはコホート月、もう1つは「使用月」です。このプロセスは、その後のコホート毎に繰り返されます。テーブルは次のようになります。

Jan 12 | Jan 12 
Jan 12 | Feb 12 
... 
Jan 12 | Mar 17 
Feb 12 | Feb 12 
Feb 12 | Mar 12 
... 
Feb 12 | Mar 17 
... 
Feb 17 | Feb 17 
Feb 17 | Mar 17 
Mar 17 | Mar 17 

問題は、既存のコホートと将来のコホートの両方について1年間の予測を行いたいので発生します。 これは、1月12日のコホートでは、4月17日から3月18日までの予測をしたいと思っています。 4月17日から3月18日までの4月17日のコホート(まだ存在しません)の予測もしたいと思います。 3月18日の3月18日のコホートの予測まで。 私は予測を扱うことができますが、それについては心配しないでください。

私の問題は、すべてのコホートが切り替わる前に、「使用月」列にこのリスト(4月17日.. 3月17日)を追加する方法がわかりません。 私はまた、コホートを4月17日から3月18日まで追加し、これらの将来のコホートごとに(4月17日... 3月17日)このリストの該当部分を持たなければなりません。

だから私は、テーブルは次のようになりたい:

Jan 12 | Jan 12 
Jan 12 | Feb 12 
... 
Jan 12 | Mar 17 
Jan 12 | Apr 17 
..  
Jan 12 | Mar 18 
Feb 12 | Feb 12 
Feb 12 | Mar 12 
... 
Feb 12 | Mar 17 
Feb 12 | Apr 17 
... 
Feb 12 | Mar 18 
...  
...  
Feb 17 | Feb 17 
Feb 17 | Mar 17  
... 
Feb 17 | Mar 18 
Mar 17 | Mar 17  
... 
Mar 17 | Mar 18 

私は心に来た最初のソリューションは、すべてのリストを作成を行うことです知っているが、クロスは自分自身にそれを参加、3月18日に1月12日の日付私が持っている現在のテーブルに外部結合を残しました(コホート/月は1月12日から3月17日の範囲です)。しかし、これはスケーラブルではありません。

翌年のこの月のリストに反復的に追加できる方法はありますか?絶対に必要な場合、私はHPのVerticaを使用しています

は、プレストまたはハイブを使用することができ

答えて

0

私はあなたが何の外に一時テーブルを作成し、クエリの残りの部分と、それに参加するためにここに以下のクエリを使用すべきだと思います。私はSQLで手続き的なやり方で何もすることはできません、私は恐れています。 CROSS JOINがなければ、あなたは逃げることができません。しかし、ここでは、CROSS JOINを、必要とする最初のペアの生成に制限します。

ここに行く:

WITH 
-- create a list of integers from 0 to 100 using the TIMESERIES clause 
i(i) AS (
SELECT dt::DATE - '2000-01-01'::DATE 
FROM ( 
      SELECT '2000-01-01'::DATE + 0 
UNION ALL SELECT '2000-01-01'::DATE + 100 
) d(d) 
TIMESERIES dt AS '1 day' OVER(ORDER BY d::TIMESTAMP) 
) 
, 
-- limits are Jan-2012 to the first of the current month plus one year 
month_limits(month_limit) AS (
      SELECT '2012-01-01'::DATE 
UNION ALL SELECT ADD_MONTHS(TRUNC(CURRENT_DATE,'MONTH'),12) 
) 
-- create the list of possible months as a CROSS JOIN of the i table 
-- containing the integers and the month_limits table, using ADD_MONTHS() 
-- and the smallest and greatest month of the month limits 
,month_list AS (
SELECT 
    ADD_MONTHS(MIN(month_limit),i) AS month_first 
FROM month_limits CROSS JOIN i 
GROUP BY i 
HAVING ADD_MONTHS(MIN(month_limit),i) <= (
    SELECT MAX(month_limit) FROM month_limits 
) 
) 
-- finally, CROSS JOIN the obtained month list with itself with the 
-- filters needed. 
SELECT 
    cohort.month_first AS cohort_month 
, use.month_first AS use_month 
FROM month_list AS cohort 
CROSS JOIN month_list AS use 
WHERE use.month_first >= cohort.month_first 
ORDER BY 1,2 
; 
関連する問題