2017-02-17 13 views
3

グループサイズが50を超えないように、Qty列の累積合計に基づいてレコードをグループ化する方法を決定しようとしています。希望するグループは、グループの列にサンプルデータ以下。SQL実行中の合計グループ化限度

これをSQL(特にSQL Server 2012)で実行する方法はありますか?

ありがとうございました。

ID  Qty  Group 
1  10  1 
2  20  1 
3  30  2 <- 60 greater than 50 so new group 
4  40  3 
5  2  3 
6  3  3 
7  10  4 
8  25  4 
9  15  4 
10  5  5 

答えて

2

CTEを使用して目標を達成できます。

項目の一つは数量50を超えた場合、グループはまだ次のクエリは、あなたが何をしたいのほとんどを与える

DECLARE @Data TABLE (ID int identity(1,1) primary key, Qty int) 
INSERT @Data VALUES (10), (20), (30), (40), (2), (3), (10), (25), (15), (5) 

;WITH cte AS 
(
    SELECT ID, Qty, 1 AS [Group], Qty AS RunningTotal FROM @Data WHERE ID = 1 
    UNION ALL 
    SELECT data.ID, data.Qty, 
     -- The group limits to 50 Qty 
     CASE WHEN cte.RunningTotal + data.Qty > 50 THEN cte.[Group] + 1 ELSE cte.[Group] END, 
     -- Reset the running total for each new group 
     data.Qty + CASE WHEN cte.RunningTotal + data.Qty > 50 THEN 0 ELSE cte.RunningTotal END 
    FROM @Data data INNER JOIN cte ON data.ID = cte.ID + 1 
) 
SELECT ID, Qty, [Group] FROM cte 
+0

このソリューションは機能しますが、サンプルデータにさらに多くの行が含まれていると、再帰が制限を超えます。非再帰的な解決策はありますか? – user824911

0

このためにストアドプロシージャを作成する必要があります。

データベースにグループ列がある場合は、グループの列をselect文で計算したい場合は、max group値とQty列の合計をフェッチして新しいレコードを挿入する際に注意が必要ですそれに応じてストアドプロシージャをコーディングする必要があります

+0

これは質問に答えません – TheGameiswar

0

それを割り当てます。結果の自己結合もう一つは、グループの大きさを計算します:

select a.ID, G, sum(b.Qty) as Total 
from (
    select max(ID) as ID, G 
    from (
     select a.ID, sum(b.Qty)/50 as G 
     from T as a join T as b 
     where a.ID >= b.ID 
     group by a.ID 
    ) as A 
    group by G 
) as a join T as b 
where a.ID >= b.ID 
group by a.ID 

ID   G   Total 
---------- ---------- ---------- 
2   0   30   
3   1   60   
8   2   140  
10   3   160  

二つの重要なトリック:

  1. 合計
  2. 使用整数の除算を実行している得るために不平等で自己結合を使用しますグループ番号を計算します。

これについては、canonical SQLページで説明します。