如何在T-SQL查询中调整行号规则:同员工同地址返回相同编号
问题根因
你当前使用的ROW_NUMBER()窗口函数的特性是,在每个分区内逐行分配全局唯一的连续序号,哪怕分区内用来排序的字段值完全重复,也会为每一行生成不同的编号,因此无法实现“同个员工下相同地址对应同个序号”的需求。
解决方案
直接将原来的ROW_NUMBER()替换为DENSE_RANK()窗口函数即可,该函数的逻辑完全匹配你的需求:
- 按
emp_code做分区 - 分区内按照
Address值比较 - 只要两行的
Address取值完全相同,就分配相同的序号 - 当
Address取值发生变化时,序号按连续规则递增,不会出现跳号
修正后的查询语句
SELECT -- 保留你原查询中需要输出的[ID]字段,不影响序号计算逻辑 [ID], emp_code, [Name], [Address], [Company], -- 替换原有的ROW_NUMBER为DENSE_RANK DENSE_RANK() OVER (PARTITION BY [emp_code] ORDER BY [Address]) AS AddressRowNumber FROM [tbl1]
结果验证
上述查询运行后输出的结果和你期望的完全一致:
emp_code Name Address Company AddressRowNumber --------------------------------------------------------- 100 Peter London ABC 1 125 Allan Cambridge DCE 1 125 Allan Cambridge DCE 1 115 John Suffolk ABC 1 115 John Suffolk XYZ 1 154 Mary Highlands ABC 1 154 Mary Bristol ABC 2 154 Mary Chester ABC 3
注意事项
- 不要使用
RANK()函数:该函数遇到重复值时会占用序号位置,出现跳号。比如Allan的两行同地址的记录,RANK()会分配两个1,后续Bristol地址的行序号会直接跳为3,不符合连续递增的要求 - 如果你的数据中Address存在前后空格、大小写不一致的情况,可以在排序时先做清洗,比如改成
ORDER BY LTRIM(RTRIM(LOWER([Address]))),避免格式问题导致相同地址被识别为不同值 - SQL Server 中
NULL值在窗口排序时会被视为相等,所有同分区下Address为NULL的行会被分配相同序号,符合常规使用预期
内容的提问来源于stack exchange,提问作者user3115933
相关产品推荐
相关产品推荐

