2016-07-20 7 views
0

毎月の毎月の収入を表示するダッシュボードを作成しようとしています。私は、これを行う最善の方法は、毎月の行とそれの横に収入があるテーブルを作成することだと思います。データの一つの行には、現在次のようになります。2か月間に複数の行を1つの行に作成するための支援が必要

Subscription_ID| Start_Date| End_Date |Monthly_revenue 
2384105  | 1/1/2016 | 6/1/2016 |500 

私は何とか次の行のように見えるように、その行を変換したい:

Subscription_ID |Month |Monthly_Revenue 
2384105   |1/1/2016 | 500 
2384105   |2/1/2016 | 500 
2384105   |3/1/2016 | 500 
2384105   |4/1/2016 | 500 
2384105   |5/1/2016 | 500 
2384105   |6/1/2016 | 500 

私もこれについて移動する方法が分かりません。あなたが正しい方向に私を指すことができれば、どんな助言も大いに評価されるでしょう。私は自分のDBとしてredshiftを使用しているので、構文はポストグルとほとんど同じです。

編集:コメントに返信 - 参考になるとすれば、すべての日付と年を含む表を簡単に作成できます。

+0

赤方偏移は、任意の2つの与えられた日付の間の日数を生成するために、再帰CTEのをサポートしていません。あなたはすべての月と年の組み合わせのテーブルがありますか? –

+0

再帰的なcteなしではまだ集計テーブルでそれを行うことができます – Matt

+0

これは伝統的にPostgreSQLで 'generate_series()'を使って行いますが、RedShiftはこれを持っていない古いバージョンに基づいています。これは、いくつかの代替メソッドが役立つかもしれません:http://stackoverflow.com/questions/22759980/generate-series-in-redhsift/34167753#34167753 – Nicarus

答えて

2

わかりました、私はこのような何かが動作する必要のあるいくつかの赤方偏移のドキュメントを見て:

DATEDIFF http://docs.aws.amazon.com/redshift/latest/dg/r_DATEDIFF_function.html

共通テーブル式http://docs.aws.amazon.com/redshift/latest/dg/r_WITH_clause.html

DATEADD http://docs.aws.amazon.com/redshift/latest/dg/r_DATEADD_function.html

WITH cteData AS (
    SELECT 
     CAST(2384105 AS INTEGER) AS Subscription_ID 
     ,CAST('2016-01-01' AS DATE) AS Start_Date 
     ,CAST('2016-06-01' AS DATE) AS End_Date 
     ,CAST(500 AS INTEGER) AS Monthly_revenue 
) 

,cteTally AS (
     SELECT 0 AS TallyNum 
     UNION ALL 
     SELECT 1 
     UNION ALL 
     SELECT 2 
     UNION ALL 
     SELECT 3 
     UNION ALL 
     SELECT 4 
     UNION ALL 
     SELECT 5 
     UNION ALL 
     SELECT 6 
     UNION ALL 
     SELECT 7 
     UNION ALL 
     SELECT 8 
     UNION ALL 
     SELECT 9 
     UNION ALL 
     SELECT 10 
     UNION ALL 
     SELECT 11 
    ) 


    SELECT 
     Subscription_ID 
     ,DATEADD(month,c.TallyNum,t.Start_date) AS "Month" 
     ,Monthly_revenue 
    FROM 
     cteData t 
     INNER JOIN cteTally c 
     ON DATEDIFF(month,t.Start_Date,t.End_Date) >= c.TallyNum 

これは、あなたのために働くことgenerate_series()またはrecursive cteを使用しません。これは私がSQLフィドル(http://sqlfiddle.com/#!15/f3a23/7/0)でこれを試してみましたPostgresSQLのバージョンです....

CREATE TABLE Tbl (
    Subscription_ID INTEGER 
    ,Start_Date DATE 
    ,End_Date DATE 
    ,Monthly_revenue INTEGER); 

INSERT INTO Tbl (Subscription_ID, Start_Date, End_Date, Monthly_revenue) 
VALUES (2384105,'2016-01-01','2016-06-01',500); 

WITH cteTally AS (
    SELECT 0 AS TallyNum 
    UNION ALL 
    SELECT 1 
    UNION ALL 
    SELECT 2 
    UNION ALL 
    SELECT 3 
    UNION ALL 
    SELECT 4 
    UNION ALL 
    SELECT 5 
    UNION ALL 
    SELECT 6 
    UNION ALL 
    SELECT 7 
    UNION ALL 
    SELECT 8 
    UNION ALL 
    SELECT 9 
    UNION ALL 
    SELECT 10 
    UNION ALL 
    SELECT 11 
) 

SELECT 
    Subscription_ID 
    ,(t.Start_Date + (c.TallyNum * '1 month'::INTERVAL)) as "Month" 
    ,Monthly_revenue 
FROM 
    Tbl t 
    INNER JOIN cteTally c 
    ON (
     (DATE_PART('year', t.End_Date) - DATE_PART('year', t.Start_Date)) * 12 
     + 
     (DATE_PART('month', t.End_Date) - DATE_PART('month', t.Start_Date)) 
    ) >= c.TallyNum 
; 
+0

ありがとう。私はこれらの慣行に精通していませんが、私はctetally redshiftでサポートされているとは思わない。これらの関数の周りには、これらの関数に関する文書はありません – Berra2k

+0

この文書では、ctTallyは一般的なテーブル式で、redshiftで動作するはずです。 http://docs.aws.amazon.com/redshift/latest/dg/r_WITH_clause.html日付までの時間機能はpostSQL版であるため、実際にはms SQLサーバは日付操作の方がずっと簡単です。 – Matt

+0

AH!私はだから私はctetallyテーブル名ではない関数だと思いました!おかげさまでこれを試してみます。また、VALUES()を持つ領域を覚えておいてください。異なる値を持つ数千の行がありますので、列名を参照できますか? – Berra2k

関連する問題