2017-02-17 53 views
3

我正在嘗試確定如何根據數量列的累計總數將記錄組合​​在一起,以便組大小不超過50個。所需組在組列中給出樣本數據下面。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

您需要爲此創建一個存儲過程。

如果您的數據庫中包含Group列,那麼在插入新記錄時通過獲取最大Group值及其Qty列總和值得關注它,否則如果您希望Group列在select語句中計算,那麼您必須相應地編碼存儲過程。

+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頁面上討論這個和其他技術。