SQL Server中移除行内重复account_name值的方案咨询
解决SQL Server同一Site下Account_Name重复问题
针对你的需求,以下是两种场景的解决方案:查询去重和永久清理表中重复数据,同时解释下你之前用DISTINCT/GROUP BY没成功的原因。
一、为什么DISTINCT和GROUP BY没效果?
如果表中除了site和account_name还有其他列(比如ID、业务字段),DISTINCT会判断整行的唯一性,只要其他列值不同就不会去重;而GROUP BY若只按site和account_name分组,直接SELECT其他非聚合列会报错(SQL Server不允许非分组列未被聚合),所以这两种方法在多列场景下无法直接实现你要的"同一site下每个account_name仅显示一次"的需求。
二、查询时去重(不修改原表)
用ROW_NUMBER()窗口函数,按site和account_name分区,取每个分区的第一条数据,适合需要保留其他列的场景:
SELECT * FROM ( SELECT *, -- 按site和account_name分组,给每组内的行编序号 ROW_NUMBER() OVER (PARTITION BY site, account_name ORDER BY id) AS rn FROM 你的表名 ) t -- 只保留每组的第一条 WHERE rn = 1;
- 若想保留最新/最旧的记录,把
ORDER BY id改成ORDER BY id DESC(最新)或ORDER BY id ASC(最旧);如果没有ID列,也可以用其他时间字段或唯一标识列排序。
三、永久删除表中的重复数据
如果要彻底清理重复项,只保留每个site+account_name组合的一条记录,用CTE结合窗口函数实现:
WITH DuplicateRecords AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY site, account_name ORDER BY id) AS rn FROM 你的表名 ) -- 删除每组中序号大于1的重复行 DELETE FROM DuplicateRecords WHERE rn > 1;
- 同样,
ORDER BY id控制保留哪一条,比如用ORDER BY create_time DESC可以保留每组中最新创建的记录。
如果表没有主键或唯一标识列,也可以用分组关联的方式删除:
DELETE t1 FROM 你的表名 t1 JOIN ( -- 找到每个site+account_name要保留的那条记录的标识(这里用MIN(id)举例) SELECT site, account_name, MIN(id) AS keep_id FROM 你的表名 GROUP BY site, account_name HAVING COUNT(*) > 1 ) t2 ON t1.site = t2.site AND t1.account_name = t2.account_name AND t1.id != t2.keep_id;
内容的提问来源于stack exchange,提问作者Gatewarden
相关产品推荐
相关产品推荐

