PostgreSQL按group_id去重并保留null行,支持SELECT *查询
解决方案:按group_id去重并保留所有null行
要实现每个非null的group_id仅返回一行(取先匹配到的),同时保留所有group_id为null的行,且使用SELECT *查询,可以借助窗口函数ROW_NUMBER()来实现,这是通用且简洁的方案:
核心SQL语句
SELECT * FROM ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY COALESCE(group_id, id) ORDER BY id -- 可根据需求调整排序规则,决定哪一行被选为"先匹配到的" ) AS rn FROM products ) t WHERE rn = 1;
逻辑说明
- 分组处理:
PARTITION BY COALESCE(group_id, id)是关键:- 当
group_id不为null时,所有同group_id的行被分到同一组 - 当
group_id为null时,用唯一的id作为分组键,让每一行单独成组
- 当
- 行编号:
ROW_NUMBER()为每个分组内的行按指定顺序(示例用id升序)编号,每组第一行编号为1 - 筛选结果:外层查询只保留编号为1的行,既实现了非null
group_id的去重,又完整保留了所有group_id为null的行
注意事项
- 该方案适用于支持窗口函数的数据库(如MySQL 8.0+、PostgreSQL、SQL Server、Oracle等)
ORDER BY子句可根据实际业务需求调整,比如按创建时间created_at排序,来决定哪一行被优先返回
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

