SQL去重需求:含空列时保留最完整行及唯一空重复行
数据库重复行去重实现
去重规则
- 以
first和last字段作为重复判断依据 - 若同一组重复行中存在数据更完整的行(非空字段更多),删除数据不完整的行
- 若同一组重复行均含空列且数据完整度一致,仅保留1条
输入示例表
| id | first | last | address | phone |
|---|---|---|---|---|
| 1 | bob | john | street1 | 1234 |
| 2 | bob | john | 1234 | |
| 3 | bob | john | street1 | |
| 4 | amir | khan | ||
| 5 | amir | khan | ||
| 6 | roby | johanson | street4 | |
| 7 | roby | johanson | street5 |
输出结果表
| id | first | last | address |
|---|---|---|---|
| 1 | bob | john | street1 |
| 4 | amir | khan | |
| 6 | roby | johanson | street4 |
| 7 | roby | johanson | street5 |
说明:行2、3因行1数据更完整被删除;行5因与行4完全重复被删除;roby组因
address不同,不属于重复行,故全部保留
实现SQL(以MySQL为例)
WITH ranked_rows AS ( SELECT *, -- 计算每行非空字段的数量,用于判断数据完整度 ( CASE WHEN first IS NOT NULL THEN 1 ELSE 0 END + CASE WHEN last IS NOT NULL THEN 1 ELSE 0 END + CASE WHEN address IS NOT NULL THEN 1 ELSE 0 END + CASE WHEN phone IS NOT NULL THEN 1 ELSE 0 END ) AS non_null_count, -- 按first+last分组,先按完整度降序,再按id升序排名 ROW_NUMBER() OVER ( PARTITION BY first, last ORDER BY non_null_count DESC, id ASC ) AS row_rank FROM your_table_name ) -- 只保留每组排名第一的行,再选择需要的字段 SELECT id, first, last, address FROM ranked_rows WHERE row_rank = 1;
代码说明
- 使用
WITH子句创建临时表ranked_rows,计算每行的非空字段数量non_null_count - 通过
ROW_NUMBER()窗口函数,按first和last分组,优先保留非空字段多的行;若完整度相同,保留id最小的行 - 最后筛选出每组排名第一的行,得到去重后的结果
内容的提问来源于stack exchange,提问作者Gnad
相关产品推荐
相关产品推荐

