为何ROW_NUMBER在处理含Null的重复ID记录时无法正常工作?
问题解决方案
核心问题在于:原表中同一ID下的Race/Ethnicity/Awards字段存在Null值,而数据库会将Null视为独立分组键(Null不等于任何值,包括其他Null),导致你原有的PARTITION BY逻辑把同一ID拆成了多个分组,最终ROW_NUMBER结果不符合预期。
下面是两种可行的解决思路,先为每个ID填充缺失的字段值,再计算ROW_NUMBER:
方法1:聚合子查询填充字段(简洁直观)
先通过GROUP BY ID提取每个ID对应的非空字段值,再关联回原表完成填充,最后基于填充后的字段分组排序:
WITH id_valid_values AS ( SELECT ID, MAX(Race) AS valid_Race, -- 每个ID的非空Race值 MAX(Ethnicity) AS valid_Ethnicity, -- 每个ID的非空Ethnicity值 MAX(Awards) AS valid_Awards -- 每个ID的非空Awards值 FROM your_table GROUP BY ID ), filled_table AS ( SELECT t.*, ivv.valid_Race, ivv.valid_Ethnicity, ivv.valid_Awards FROM your_table t JOIN id_valid_values ivv ON t.ID = ivv.ID ) SELECT *, ROW_NUMBER() OVER ( PARTITION BY ID, valid_Race, valid_Ethnicity, valid_Awards ORDER BY EthnicityID ASC ) AS row_num FROM filled_table;
方法2:窗口函数直接填充(无需关联子查询)
利用窗口函数在每个ID分组内直接提取非空字段值,一步完成填充和ROW_NUMBER计算:
SELECT *, -- 提取ID分组内的非空Race值 MAX(Race) OVER (PARTITION BY ID) AS filled_Race, -- 提取ID分组内的非空Ethnicity值 MAX(Ethnicity) OVER (PARTITION BY ID) AS filled_Ethnicity, -- 提取ID分组内的非空Awards值 MAX(Awards) OVER (PARTITION BY ID) AS filled_Awards, -- 基于填充后的字段计算ROW_NUMBER ROW_NUMBER() OVER ( PARTITION BY ID, MAX(Race) OVER (PARTITION BY ID), MAX(Ethnicity) OVER (PARTITION BY ID), MAX(Awards) OVER (PARTITION BY ID) ORDER BY EthnicityID ASC ) AS row_num FROM your_table;
为什么之前的尝试没彻底解决?
- 单独用
MIN/MAX+GROUP BY:会丢失原表的其他细节字段,无法保留所有原始行数据; - 直接筛选
ROW_NUMBER = 1:原逻辑因为Null拆分了分组,导致每个分组的第1行可能还是带Null的记录,无法覆盖所有情况。
内容的提问来源于stack exchange,提问作者Amit Desai
相关产品推荐
相关产品推荐

