原表无分组标识时,如何在SQL Server中实现分组及成员编号?
问题描述
原始数据表:
| Name | Rol | FirstDate |
|---|---|---|
| Alice | Leader | 01-01-2020 |
| Bob | Follower | 01-05-2020 |
| Charles | Follower | 03-06-2020 |
| Art | Leader | 04-01-2021 |
| Will | Leader | 05-01-2022 |
| Susy | Follower | 06-01-2023 |
期望结果:
| Name | Rol | GroupId | MemberId |
|---|---|---|---|
| Alice | Leader | 1 | 1 |
| Bob | Follower | 1 | 2 |
| Charles | Follower | 1 | 3 |
| Art | Leader | 2 | 1 |
| Will | Leader | 3 | 1 |
| Susy | Follower | 3 | 2 |
规则:每当Rol字段值为Leader时创建新分组,每个分组内生成连续的MemberId。
解决方案
可以通过累计求和生成GroupId,再结合ROW_NUMBER()函数生成分组内的MemberId,SQL代码如下:
SELECT Name, Rol, -- 累计统计Leader出现次数,生成连续分组ID SUM(CASE WHEN Rol = 'Leader' THEN 1 ELSE 0 END) OVER (ORDER BY FirstDate) AS GroupId, -- 按分组ID分区,生成组内连续编号 ROW_NUMBER() OVER (PARTITION BY SUM(CASE WHEN Rol = 'Leader' THEN 1 ELSE 0 END) OVER (ORDER BY FirstDate) ORDER BY FirstDate) AS MemberId FROM your_table_name ORDER BY FirstDate;
代码解释
- GroupId生成:利用
SUM() OVER (ORDER BY FirstDate)对所有行按日期排序,每遇到Rol='Leader'的行就累计加1,自动生成连续的分组ID。 - MemberId生成:以生成的
GroupId作为分区条件,用ROW_NUMBER()函数在每个分组内按日期排序,生成从1开始的连续编号。
如果数据库支持CTE(公共表达式),可以将分组ID的计算逻辑抽离,让代码更易读:
WITH grouped_data AS ( SELECT Name, Rol, FirstDate, SUM(CASE WHEN Rol = 'Leader' THEN 1 ELSE 0 END) OVER (ORDER BY FirstDate) AS GroupId FROM your_table_name ) SELECT Name, Rol, GroupId, ROW_NUMBER() OVER (PARTITION BY GroupId ORDER BY FirstDate) AS MemberId FROM grouped_data ORDER BY FirstDate;
内容的提问来源于stack exchange,提问作者Diego R.
相关产品推荐
相关产品推荐

