SQL Server 使用 ROW_NUMBER 去重:保留唯一记录并删除重复数据

Felix
Felix
发布时间:2026-10-15 | 2人浏览过
原创

在处理数据库数据清洗时,经常需要针对包含重复值的表格进行去重操作。本方法利用 SQL Server 的窗口函数 ROW_NUMBER(),通过为每组重复数据分配序号,进而执行 DELETE 语句移除序号大于 1 的记录。该方案逻辑清晰、执行精确,能有效避免误删重要数据。

构建测试环境与准备数据

首先,我们需要创建一个示例表来模拟存在重复数据的场景。我们将建立一个名为 test_delete 的表,包含姓名(name)和数值(value)两个字段,并插入包含若干重复项的数据集,以便后续验证去重效果。

-- 创建测试表
CREATE TABLE test_delete(
    name varchar(10),
    value INT
);
GO

-- 插入测试数据
-- 张三100 有两条重复,王五80 有两条重复,其他为单条或不同值
INSERT INTO test_delete 
SELECT '张三', 100
UNION ALL SELECT '张三', 100
UNION ALL SELECT '李四', 80
UNION ALL SELECT '王五', 80
UNION ALL SELECT '王五', 80
UNION ALL SELECT '赵六', 90
UNION ALL SELECT '赵六', 70;
GO

插入完成后,我们可以先查询当前表中的数据状态,确认重复项确实存在:

SELECT * FROM test_delete;

识别重复数据并标记行号

要删除重复数据,核心思路是为每一组完全相同的记录(即 name 和 value 均相同)打上唯一的行号标识。如果某组数据只有 1 条记录,其行号为 1;如果有 N 条重复记录,则分别标记为 1 到 N。

我们使用 ROW_NUMBER() 窗口函数来实现这一点:
- PARTITION BY name, value:按这两个字段的组合进行分组。
- ORDER BY (SELECT 1):对组内记录排序,由于只关心是否重复,内部顺序不影响结果,固定返回 1 即可。

SELECT 
    ROW_NUMBER() OVER (PARTITION BY name, value ORDER BY (SELECT 1)) AS no,
    name,
    value 
FROM 
    test_delete;

执行上述查询后,可以看到如下结果。注意观察 no 列,对于“张三”和“王五”,no 出现了 1 和 2,表明这两行数据是重复的。

no  name     value
-------------------- ---------- -----------
1   李四     80
1   王五     80
2   王五     80
1   张三     100
2   张三     100
1   赵六     70
1   赵六     90

执行去重操作

虽然可以直接使用临时表或 CTE(公用表表达式),但为了展示基础逻辑,这里演示通过创建视图来进行删除操作(生产环境中建议优先使用 CTE 以避免冗余对象)。我们将刚才的行号查询逻辑封装为一个视图,然后针对该视图执行删除指令。

第1步:创建辅助视图

目的:将复杂的行号计算逻辑固化,简化后续的 DELETE 语句编写。

-- 创建视图,用于存储行号标记
CREATE VIEW tmp_view AS 
SELECT 
    ROW_NUMBER() OVER (PARTITION BY name, value ORDER BY (SELECT 1)) AS no,
    name,
    value 
FROM 
    test_delete;

第2步:执行 DELETE 删除多余数据

动作:从视图中删除行号不等于 1 的记录,从而保留每组重复数据中的第一条,移除其余重复项。

-- 删除所有行号不为1的记录
DELETE FROM tmp_view WHERE no != 1;

系统反馈显示受影响的行数,这代表了被成功移除的重复数据量。在本例中,“张三”多出一条、“王五”多出一条,因此影响行数应为 2 行。

验证去重结果

删除操作完成后,需再次查询原表以确认数据是否已按照预期精简。

SELECT * FROM test_delete;

预期结果如下,所有重复的条目均已消失,仅保留了各组的第一条唯一记录:

name     value
---------- -----------
张三     100
李四     80
王五     80
赵六     90
赵六     70

总计剩余 5 行数据,验证了去重操作的准确性。

总结与建议

通过 ROW_NUMBER() 配合 DELETE 语句是 SQL Server 中非常经典的数据去重手段。该方法的关键在于正确设置 PARTITION BY 字段,以确保分组逻辑符合业务需求(例如可能需要忽略主键或其他ID字段)。尽管视图法演示了直观的流程,但在实际工程实践中,直接使用 Common Table Expression (CTE) 会更简洁高效,且无需在数据库中残留临时视图对象。

以上就是SQL Server使用ROW_NUMBER去重的详细内容,更多关于SQL数据库优化的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表