基于指定列唯一值为TSQL数据分组并生成连续组编号
TSQL实现按多列唯一组合分配连续分组编号
问题场景
现有如下结构的表(右侧包含其他各类列):
| ID | ColA | ColB | ColC | ... |
|---|---|---|---|---|
| 1 | 111 | XXX | foo | |
| 1 | 111 | XXX | bar | |
| ... | ... | ... | ... | |
| 1 | 111 | YYY | foo | |
| 1 | 111 | YYY | bar | |
| ... | ... | ... | ... | |
| 1 | 999 | XXX | foo | |
| 1 | 999 | XXX | bar | |
| ... | ... | ... | ... | |
| 1 | 999 | YYY | foo | |
| 1 | 999 | YYY | bar | |
| ... | ... | ... | ... | |
| 2 | 111 | XXX | foo | |
| 2 | 111 | XXX | bar | |
| ... | ... | ... | ... |
需求:仅依据ID、ColA、ColB列的唯一组合对表分组,为每个组分配全局连续的GroupNumber,最终结果示例如下:
| ID | ColA | ColB | ColC | ... | GroupNumber |
|---|---|---|---|---|---|
| 1 | 111 | XXX | foo | 1 | |
| 1 | 111 | XXX | bar | 1 | |
| ... | ... | ... | ... | ... | |
| 1 | 111 | YYY | foo | 2 | |
| 1 | 111 | YYY | bar | 2 | |
| ... | ... | ... | ... | ... | |
| 1 | 999 | XXX | foo | 3 | |
| 1 | 999 | XXX | bar | 3 | |
| ... | ... | ... | ... | ... | |
| 1 | 999 | YYY | foo | 4 | |
| 1 | 999 | YYY | bar | 4 | |
| ... | ... | ... | ... | ... | |
| 2 | 111 | XXX | foo | 5 | |
| 2 | 111 | XXX | bar | 5 | |
| ... | ... | ... | ... | ... |
错误尝试及问题
尝试使用以下SQL实现,但不符合需求:
SELECT *, DENSE_RANK() OVER( PARTITION BY ID, ColA, ColB ORDER BY ColC ) AS GroupNumber FROM my_table
问题原因:PARTITION BY ID, ColA, ColB会将每一组ID+ColA+ColB的组合拆分为独立分区,之后在分区内按ColC排序生成编号,导致同一组合内的行因为ColC值不同而得到不同的GroupNumber,无法实现同一组编号一致的要求。
正确实现方案
使用DENSE_RANK()函数,去掉不必要的PARTITION BY,直接按ID、ColA、ColB排序即可:
SELECT *, DENSE_RANK() OVER(ORDER BY ID, ColA, ColB) AS GroupNumber FROM my_table
方案说明
DENSE_RANK()会为所有行中ORDER BY子句指定的列(ID、ColA、ColB)值完全相同的行分配同一个编号- 编号会全局连续递增,不会因为重复组合而跳过数字,完全符合需求中"每个唯一组合对应连续GroupNumber"的要求
内容的提问来源于stack exchange,提问作者Antimon
相关产品推荐
相关产品推荐

