You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server 2016删除双列重复行及现有查询异常咨询

你的查询问题分析&删除重复行的正确方法

咱们先拆解下你原查询的问题,再一步步解决删除重复行的需求:

原查询为啥返回全表?

你的查询逻辑完全偏离了“找CertID+ResponseDueDate组合重复”的需求,问题出在这几点:

  • CTE A的DISTINCT无效:你用了DISTINCT ID, ResponseDueDate, CertID,但ID是表的唯一标识(看你的示例数据,每行ID都不一样),所以每一行的这三个字段组合都是唯一的,DISTINCT等于没加,A其实就是原表的全部数据。
  • CTE B的分组逻辑错误:你按CertID分组并筛选COUNT(*) >1,这是在找“对应多个行的CertID”,但你的需求是找“CertID+ResponseDueDate组合重复”的行。示例数据里所有行的CertID都是48983,所以B会包含这个CertID,最后关联后自然返回全表。

如何删除多余的重复行(保留每组组合的一行)?

针对SQL Server 2016,推荐两种可靠的方法,操作前一定要先备份数据,或者先执行SELECT确认要删除的行,避免误删:

方法1:用ROW_NUMBER()窗口函数(逻辑最清晰)

给每个CertID+ResponseDueDate组合的行分配编号,保留编号为1的行,删除编号大于1的。你可以通过ORDER BY指定保留哪一行(比如保留ID最小的,或者最新的记录):

先确认要删除的行:

SELECT 
    ID, CertID, ResponseDueDate,
    -- 按组合分组,给行编号,ID小的排前面
    ROW_NUMBER() OVER(PARTITION BY CertID, ResponseDueDate ORDER BY ID) AS RowNum
FROM FacCompliance
ORDER BY CertID, ResponseDueDate, RowNum;

执行删除:

WITH DuplicateRows AS (
    SELECT 
        ID,
        ROW_NUMBER() OVER(PARTITION BY CertID, ResponseDueDate ORDER BY ID) AS RowNum
    FROM FacCompliance
)
DELETE FROM DuplicateRows
WHERE RowNum > 1;

如果想保留ID最大的行,把ORDER BY ID改成ORDER BY ID DESC即可。

方法2:用自连接删除

通过自连接找到重复组合中需要删除的行(比如ID更大的行),直接删除:

DELETE f1
FROM FacCompliance f1
JOIN FacCompliance f2 
    ON f1.CertID = f2.CertID 
    AND f1.ResponseDueDate = f2.ResponseDueDate
    AND f1.ID > f2.ID; -- 保留ID较小的行,删除ID更大的重复行

内容的提问来源于stack exchange,提问作者NoBullMan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:31:57