如何按parent_id分组,同时保留所有null值行及非null值的去重记录?
解决方案
可以通过分组聚合+联合查询或窗口函数的方式实现需求:
原始数据
| id | parent_id |
|---|---|
| 1 | null |
| 2 | null |
| 3 | 1 |
| 4 | 1 |
| 5 | 1 |
预期结果
| id | parent_id |
|---|---|
| 1 | null |
| 2 | null |
| 3 | 1 |
方法一:联合查询+分组聚合
-- 保留所有parent_id为null的记录 SELECT id, parent_id FROM your_table_name WHERE parent_id IS NULL UNION ALL -- 对parent_id非null的记录,按parent_id分组取单条(这里取id最小的记录) SELECT MIN(id) AS id, parent_id FROM your_table_name WHERE parent_id IS NOT NULL GROUP BY parent_id;
逻辑说明
- 第一部分直接筛选并保留所有
parent_id为null的记录; - 第二部分针对非
null的parent_id分组,通过MIN(id)提取每组中id最小的记录(若需要保留其他规则的记录,可替换为MAX(id)或对应字段的聚合函数); - 用
UNION ALL合并两部分结果,得到最终数据集。
方法二:窗口函数(适用于MySQL 8.0+、PostgreSQL等支持窗口函数的数据库)
SELECT id, parent_id FROM ( SELECT id, parent_id, -- 按parent_id分组,给每条记录排序,非null组的第一条标记为1 ROW_NUMBER() OVER (PARTITION BY parent_id ORDER BY id) AS rn FROM your_table_name ) t WHERE parent_id IS NULL OR rn = 1;
逻辑说明
- 内层查询通过
ROW_NUMBER()窗口函数,按parent_id分组并对组内记录按id排序,每组第一条记录的rn值为1; - 外层筛选保留
parent_id为null的所有记录,以及非null组中rn=1的单条记录; - 排序规则可按需调整,比如
ORDER BY id DESC可保留每组id最大的记录。
内容的提问来源于stack exchange,提问作者Martin Sojka
相关产品推荐
相关产品推荐

