SQL技术问询:如何在单表中合并唯一记录与去重后的重复记录
解决SQL中同时获取唯一条目与重复条目去重结果的问题
嘿,作为SQL新手碰到这种需求完全没问题,我来一步步帮你搞定!
首先明确你的需求:你需要从数据表中同时拿到两类数据——所有本身没有重复的唯一条目,以及那些存在重复的记录的去重版本。结合你给出的样例数据,最终结果应该包含Bottles、Cars、Trains的单条记录,再加上去重后的Boats(1-15-18的9、1-16-18的7)和Plains(1-16-18的8)这些记录。
下面给你两种实用的解决方案:
方法一:使用UNION结合分组筛选
这种方法逻辑直观,分两部分查询后合并结果:
-- 1. 筛选出所有仅出现一次的唯一条目 SELECT Date, Code, Units FROM your_table GROUP BY Date, Code, Units HAVING COUNT(*) = 1 UNION -- 2. 筛选出存在重复的记录,并去重 SELECT DISTINCT Date, Code, Units FROM your_table WHERE (Date, Code, Units) IN ( SELECT Date, Code, Units FROM your_table GROUP BY Date, Code, Units HAVING COUNT(*) > 1 )
逻辑解释:
- 第一部分通过
GROUP BY按Date, Code, Units分组,用HAVING COUNT(*) = 1筛选出只出现过一次的记录(也就是唯一条目)。 - 第二部分先通过子查询找出所有出现次数大于1的记录组合,再用
DISTINCT对这些重复记录去重。 - 最后用
UNION将两部分结果合并(UNION会自动去重,避免两部分出现重复数据)。
方法二:使用窗口函数(更简洁高效)
如果你的SQL支持窗口函数(比如MySQL 8+、PostgreSQL、SQL Server等),可以用这种更简洁的方式:
WITH record_groups AS ( SELECT Date, Code, Units, -- 计算每个记录组合的出现次数 COUNT(*) OVER (PARTITION BY Date, Code, Units) AS occurrence_count, -- 给每个记录组内的记录编号 ROW_NUMBER() OVER (PARTITION BY Date, Code, Units ORDER BY (SELECT NULL)) AS row_num FROM your_table ) SELECT Date, Code, Units FROM record_groups -- 筛选条件:要么是唯一条目(出现次数=1),要么是重复组的第一条记录(去重) WHERE occurrence_count = 1 OR row_num = 1 -- 可根据需求调整排序 ORDER BY Date, Code
逻辑解释:
- 首先用CTE(公共表表达式)给每条记录标记两个值:
occurrence_count是该Date, Code, Units组合的总出现次数,row_num是该组合内的记录序号。 - 然后筛选时,要么选出现次数为1的记录(唯一条目),要么选每个组合的第一条记录(实现重复记录的去重)。
- 最后可以加
ORDER BY来整理结果顺序,让输出更清晰。
注意事项:
- 记得把代码里的
your_table替换成你实际的数据表名称。 - 如果用窗口函数的方法,
ORDER BY (SELECT NULL)是为了在不关心组内排序时快速生成序号,你也可以换成实际的排序字段(比如Date)。
内容的提问来源于stack exchange,提问作者gary
相关产品推荐
相关产品推荐

