按行的出现分组

Posted

技术标签:

【中文标题】按行的出现分组【英文标题】:Group by occurrence of row 【发布时间】:2015-05-15 06:48:41 【问题描述】:

有一个如下表,我必须根据 group by 来计算 col2 的总和。但它属于一个链,如果链断裂,那么 sum 将被限制为序列。

DECLARE @TabVar TABLE
(
  ID INT IDENTITY(1,1), col1 varchar(20), Col2 INT
)
INSERT INTO @TabVar
VALUES ('a',2),('a',3),('b',4),('b',2),('a',6),('a',3),('b',3)

SELECT * FROM @TabVar

 Expected output:
  COL1     SUM(COL2)
  A          5
  B          6
  A          9
  B          3

我尝试使用排名函数来进行排名,但排名是使用累积 Col1 总数的 Order 完成的

【问题讨论】:

【参考方案1】:

您可以使用ROW_NUMBER()PARTITION BY,然后使用GROUP BY 来实现此目的。

每当您的链断裂时,id - ROW_NUMBER()over(partition by col1 order by id) 将具有相同的 col1 值的不同值。然后,您可以将其与col1 一起使用来对您的数据进行分组并执行SUM。像这样的

样本数据

DECLARE @TabVar TABLE
(
  ID INT IDENTITY(1,1), col1 varchar(20), Col2 INT
)
INSERT INTO @TabVar
VALUES ('a',2),('a',3),('b',4),('b',2),('a',6),('a',3),('b',3)

查询

SELECT Col1,SUM(Col2) sumcol
FROM
(
SELECT id - ROW_NUMBER()over(partition by col1 order by id) grpcol,Col1,Col2,id
FROM @TabVar
)T
GROUP BY grpcol,Col1
ORDER BY MAX(ID)

输出

Col1 sumcol
a   5
b   6
a   9
b   3

编辑

如果你的IDs 在直播环境中不是连续的,你可以使用这个

SELECT Col1,SUM(Col2) sumcol
FROM
(
SELECT ROW_NUMBER()over(order by id)  - ROW_NUMBER()over(partition by col1 order by id) grpcol, Col1,Col2,id
FROM @TabVar
)T
GROUP BY grpcol,Col1
ORDER BY MAX(ID)

【讨论】:

Identities may not be consecutive:检查此***.com/questions/14642013/…。在某些情况下它会失败。例如获取这些数据并运行您的查询: DECLARE @TabVar TABLE (ID INT, col1 varchar(20), Col2 INT) INSERT INTO @TabVar VALUES (1,'a',2),(3,'a',3 ),(4,'b',4),(5,'b',2),(6,'a',6),(7,'a',3),(8,'b',3 ) @DeepakPawar - 我的解决方案基于 OP 提供的当前示例。这里id 将是连续的,因为不涉及RESEED 或事务回滚,这是身份不连续的主要原因。更通用的解决方案是row_number() over(order by id)

以上是关于按行的出现分组的主要内容,如果未能解决你的问题,请参考以下文章

按行过滤分组

Spark窗口函数按行中最常见的值聚合

统计某字符串在文件中出现的次数

按行值分组的列总和

MySQL - 按行列表中的某个值分组

按行分组时如何合并熊猫数据框的字典