MS SQL如何实现类似DISTINCT去重同时保留原顺序及同值多段记录
解决方案
这是典型的连续重复值分组(又称「岛屿问题」)场景,不需要游标或临时表,仅用窗口函数即可实现,兼容SQL Server 2008及以上所有版本。
实现思路
利用两个行号的差值对连续出现的相同Bcolumn值做分组,同一个值如果断开后再次出现会被分到不同的组,不会被合并,分组后每组取任意一条记录即可满足连续去重需求,最后按原数据顺序排序即可。
实现代码
WITH CTE_ContinuousGroups AS ( SELECT Id, Bcolumn, -- 全局按原顺序(此处用Id排序,可替换为实际排序字段)生成行号 ROW_NUMBER() OVER (ORDER BY Id) -- 按Bcolumn分组后按原顺序生成行号 - ROW_NUMBER() OVER (PARTITION BY Bcolumn ORDER BY Id) AS GroupIdentifier FROM 你的表名 -- 替换为实际表名 ) SELECT MAX(Id) AS Id, -- 若需要组内第一条可换为MIN(Id) Bcolumn FROM CTE_ContinuousGroups GROUP BY GroupIdentifier, Bcolumn ORDER BY MIN(Id) -- 严格保留原数据顺序
效果验证
用你提供的示例数据执行上述代码,输出结果和你给出的预期结果完全一致:
| Id | Bcolumn |
|---|---|
| 124 | 5 |
| 125 | 6 |
| 126 | 7 |
| 130 | 8 |
| 133 | 5 |
补充说明
- 如果你的表排序依据不是Id,把所有
ORDER BY Id的位置替换为实际的排序字段即可 - 该方案性能远优于游标/临时表方案,支持大数据量高效运行
- 无需升级数据库,完全兼容SQL Server 2008版本
内容的提问来源于stack exchange,提问作者Ash
相关产品推荐
相关产品推荐

