SQL使用row_number()计数时如何让PERSON_ID为null的行返回null计数值
问题原因
SQL标准中,PARTITION BY会将所有PERSON_ID = NULL的行归为同一个独立分组,因此你原来的写法会给这部分行也分配连续的计数值。
实现方案
最通用且可读性最高的方案是用CASE语句对PERSON_ID做非空判断,仅当PERSON_ID不为空时返回序号:
select PERSON_ID, TIMESTAMP, CASE WHEN PERSON_ID IS NOT NULL THEN row_number() over (partition by PERSON_ID order by TIMESTAMP asc) ELSE NULL END as PERSON_COUNTER from table1;
方案优势
- 兼容所有支持窗口函数的SQL引擎(MySQL 8.0+/PostgreSQL/Oracle/Spark SQL/Hive等均可正常运行)
- 完全保留原有非空
PERSON_ID的计数逻辑,序号不会发生变化 - 不需要过滤原表数据,
PERSON_ID为空的行依然会保留,仅计数字段返回NULL
可选简化写法
如果你使用的SQL方言支持IIF函数,也可以写成更精简的形式:
select PERSON_ID, TIMESTAMP, IIF(PERSON_ID IS NOT NULL, row_number() over (partition by PERSON_ID order by TIMESTAMP asc), NULL) as PERSON_COUNTER from table1;
内容的提问来源于stack exchange,提问作者Ezer K
相关产品推荐
相关产品推荐

