2016-06-24 8 views
2

私はDiodeSalesと呼ぶ)テーブルを持っています。これは、私が作成したダイオードの総販売数、日付、ダイオードの色、国によってグループ化されています。これは、このスキーマのサンプルです:SQLでの売上合計の日次スナップショットを計算するにはどうすればよいですか?

 
Date      Color Country Sales 
June, 20 2016 00:00:00 Green US  1   
June, 20 2016 00:00:00 Red  Japan  1   
June, 20 2016 00:00:00 Red  US  1   
June, 21 2016 00:00:00 Red  US  1   
June, 22 2016 00:00:00 Green US  1   
June, 22 2016 00:00:00 Red  US  1   
June, 23 2016 00:00:00 Green US  1   
June, 23 2016 00:00:00 Red  Japan  1   
June, 23 2016 00:00:00 Red  US  1   
June, 24 2016 00:00:00 Green US  1   
June, 24 2016 00:00:00 Red  US  1    

私たちはその時点まで販売したどのように多くのダイオード私に語った追加の列を持って持つことができるようにしたいです。たとえば、上記のデータを使用すると、{6月23日、赤、1、米国}の行は、その時点で米国で4個の赤色ダイオードを販売しているため、総販売額は4になります。

私は当初、累積合計がこのトリックを行うと考えました。だから私はこれを書いた:(sqlfiddle here

SELECT 
    t1.Date, 
    t1.Color, 
    t1.Country, 
    t1.Sales, 
    SUM(t2.Sales) AS CumulativeSales 
FROM DiodeSales AS t1 
INNER JOIN DiodeSales AS t2 
ON t1.Date >= t2.Date 
    AND t1.Color = t2.Color 
    AND t1.Country = t2.Country 
GROUP BY 
    t1.Date, 
    t1.Color, 
    t1.Country 

を予想通りこれは、私の累積和を与えるが、それは私に与えられた日に指定した国の特定の色の総売上高を与えるものではありません。特に、一部の国では特定の日数で売上が0になることがあるため、関連する累積値はありません。例えば、前の表の結果を考慮してください。私はそこに、その日にセールジャパンがなかったので、6月24日に日本に対応する欄には、私は(何も見つからないだろう探しした場合

 
Date      Color Country Sales CumulativeSales 
June, 20 2016 00:00:00 Green US  1  1 
June, 20 2016 00:00:00 Red  Japan  1  1 
June, 20 2016 00:00:00 Red  US  1  1 
June, 21 2016 00:00:00 Red  US  1  2 
June, 22 2016 00:00:00 Green US  1  2 
June, 22 2016 00:00:00 Red  US  1  3 
June, 23 2016 00:00:00 Green US  1  3 
June, 23 2016 00:00:00 Red  Japan  1  2 
June, 23 2016 00:00:00 Red  US  1  4 
June, 24 2016 00:00:00 Green US  1  4 
June, 24 2016 00:00:00 Red  US  1  5 

その日は日本列ではない)。私はSQLでこれを行う方法はないと思っていますが、一部の国で売上がなかった日にこの結果テーブルに値を設定することは可能ですか?開始表には、一部の国で毎日少なくとも1つの列が常に表示されます。

私はちょうどこの情報を取得するために、単純な

 
SELECT SUM(Sales) FROM DiodeSales 
WHERE Date <= @someDate AND Color = @someColor AND Country = @someCountry 

を書くことができ、これは、それはalready-の別の部分で使用するためにそのようにフォーマットする必要があり、テーブルのためです承知しています製作されたソフトウェア。

EDIT:これは潜在的な重複として計算されますRunning Total in SQL Serverを計算しますが、そのポストは実行中の合計を計算する際の効率性のみに対処します。私はすでにこの合計を計算するさまざまな方法を持っていますが、その国に売り上げがなかった日の日/国の組み合わせが見つからないという問題を修正する方法を探しています。上記の例では、固定クエリは、この戻ってくる:

 
Date      Color Country Sales CumulativeSales 
June, 20 2016 00:00:00 Green US  1  1 
June, 20 2016 00:00:00 Red  Japan  1  1 
June, 20 2016 00:00:00 Red  US  1  1 
June, 21 2016 00:00:00 Green US  0  1 
June, 21 2016 00:00:00 Red  Japan  0  1 
June, 21 2016 00:00:00 Red  US  1  2 
June, 22 2016 00:00:00 Green US  1  2 
June, 22 2016 00:00:00 Red  Japan  0  1 
June, 22 2016 00:00:00 Red  US  1  3 
June, 23 2016 00:00:00 Green US  1  3 
June, 23 2016 00:00:00 Red  Japan  1  2 
June, 23 2016 00:00:00 Red  US  1  4 
June, 24 2016 00:00:00 Green US  1  4 
June, 24 2016 00:00:00 Red  Japan  0  2 
June, 24 2016 00:00:00 Red  US  1  5 
+0

追加タグへのSQL-ServerとSQL-SERVER-2016をお試しください。 –

+2

[SQL Serverでの実行中の合計の計算]の可能な複製(0120-919-03) –

+0

質問にSQL-Server- SQLFiddleはMySQL用に作成されています。どちらが本当ですか? –

答えて

3

これを試してみてください:

SELECT [Date], Color, Country, Sales, 
    SUM(Sales) OVER(PARTITION BY Color, Country ORDER BY [Date] rows unbounded preceding) as RunningTotal 
FROM YourTable 
ORDER BY [Date], Color 

予想通りそれは出力を生成します。

[EDIT]

あなたが欠落している日付、国や色のためのソリューションを探しているなら、この(あなたのテーブルの名前で@tmpを置き換え)してみてください。クエリの上に

SELECT A.[Date], A.Color, A.Country, COALESCE(B.Sales, 0) AS Sales 
    , SUM(COALESCE(B.Sales, 0)) OVER(PARTITION BY A.Color, A.Country ORDER BY A.[Date] rows unbounded preceding) as RunningTotal 
FROM (
    SELECT [Date], Color, Country 
    FROM (SELECT DISTINCT [Date] FROM @tmp) AS q1 CROSS JOIN 
     (SELECT DISTINCT Color FROM @tmp) AS q2 CROSS JOIN 
     (SELECT DISTINCT Country FROM @tmp) AS q3 
    ) AS A 
LEFT JOIN @tmp AS B ON A.[Date] = B.[Date] AND A.Color= B.Color AND A.Country = B.Country 
ORDER BY A.[Date], A.Color 

Date Color  Country Sales RunningTotal 
2016-06-20 Green Japan 0  0 
2016-06-20 Green US  1  1 
2016-06-20 Red  Japan 1  1 
2016-06-20 Red  US  1  1 
2016-06-21 Green US  0  1 
2016-06-21 Green Japan 0  0 
2016-06-21 Red  US  1  2 
2016-06-21 Red  Japan 0  1 
2016-06-22 Green Japan 0  0 
2016-06-22 Green US  1  2 
2016-06-22 Red  Japan 0  1 
2016-06-22 Red  US  1  3 
2016-06-23 Green US  1  3 
2016-06-23 Green Japan 0  0 
2016-06-23 Red  US  1  4 
2016-06-23 Red  Japan 1  2 
2016-06-24 Green Japan 0  0 
2016-06-24 Green US  1  4 
2016-06-24 Red  Japan 0  2 
2016-06-24 Red  US  1  5 
+0

これは私の質問と同じ結果をもたらします。そのため、紛失した国々との間に問題が残っています。 –

+0

申し訳ありません、 'PARTITION BY ... 'の後に' [Date] 'を追加してください。 –

+0

@FedericoParedes、今私の答えを確認してください。 –

2

内部結合の代わりに左結合を使用するといいと思います

SELECT 
t.Date, 
t.Color, 
t.Country, 
t.CumulativeSales 
from DiodeSales t 
left join 
(SELECT 
t1.Date, 
t1.Color, 
t1.Country, 
t1.Sales, 
SUM(t2.Sales) AS CumulativeSales 
FROM DiodeSales AS t1 
    GROUP BY 
    t1.Date, 
    t1.Color, 
t1.Country) t2 
    on 
t.Date=t2.date 
and t.Color=t2.color 
and t.Country=t2.country 
+0

なぜそれを達成するためのシンプルな方法がある場合は、ドアを広く開きますか? –

+0

Sir私は実際には私はSQLクエリで新しいです。 –

+0

同じテーブルに参加しているので、これはINNER JOINクエリと同じように動作しませんか? –

0

この

Select distinct Date into SalesDate From DiodeSales 

    SELECT S.Date,t.Color,t.Country,t.CumulativeSales 
    from DiodeSales t left join 
    (SELECt t1.Date,t1.Color,t1.Country,t1.Sales, 
    SUM(t2.Sales) AS CumulativeSales FROM DiodeSales AS t1 
     GROUP BY 
     t1.Date, 
     t1.Color, 
    t1.Country) t2 on 
     S.Date=t2.date 
    and t.Color=t2.color 
     and t.Country=t2.country 
     join 
     SalesDate S 
     on t.date=S.date 
関連する問題