SQL运行总计按限制分组

时间:2017-02-17 05:38:56

标签: sql sql-server

我正在尝试确定如何根据数量列的累计总数将记录组合​​在一起,以便组大小不超过50.所需的组在组列中给出,下面有示例数据。

有没有办法在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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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. 使用整数除法计算组编号。
  3. 我在canonical SQL页面上讨论了这个和其他技巧。

答案 2 :(得分:-1)

您需要为此创建存储过程。

如果您的数据库中有Group列,那么您必须在插入新记录时通过获取max Group值及其Qty列的总和来处理它,否则如果您希望在select语句中计算Group列,那么您有相应地编写存储过程。