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

SQL Server中删除存在多对多关联的表的重复行解决方案咨询

解决SQL Server多对多关联表中重复行的删除问题

首先,强烈建议先备份表A和AB的数据,避免误操作导致数据丢失!接下来我们分步骤解决你的问题:

1. 排查级联删除不生效的原因

你提到手动删除表A记录时级联未生效,首先要确认外键约束的ON DELETE CASCADE是否正确配置:

检查外键约束配置

执行以下SQL查询,查看AB表的外键删除规则:

SELECT 
    f.name AS ForeignKeyName,
    OBJECT_NAME(f.parent_object_id) AS ParentTable,
    c.name AS ParentColumn,
    OBJECT_NAME(f.referenced_object_id) AS ReferencedTable,
    rc.name AS ReferencedColumn,
    f.delete_referential_action_desc AS DeleteAction
FROM 
    sys.foreign_keys f
JOIN 
    sys.foreign_key_columns fkc ON f.object_id = fkc.constraint_object_id
JOIN 
    sys.columns c ON fkc.parent_object_id = c.object_id AND fkc.parent_column_id = c.column_id
JOIN 
    sys.columns rc ON fkc.referenced_object_id = rc.object_id AND fkc.referenced_column_id = rc.column_id
WHERE 
    OBJECT_NAME(f.parent_object_id) = 'AB' OR OBJECT_NAME(f.referenced_object_id) = 'AB';

如果查询结果中DeleteAction不是CASCADE,需要重新创建外键并添加级联删除规则:

重建ID_A的外键(示例)

-- 先删除原外键(替换为你的外键实际名称)
ALTER TABLE AB DROP CONSTRAINT FK_AB_ID_A;

-- 重建外键并启用级联删除
ALTER TABLE AB 
ADD CONSTRAINT FK_AB_ID_A 
FOREIGN KEY (ID_A) REFERENCES A(ID_A) 
ON DELETE CASCADE;

同理,对ID_B的外键执行相同操作(确保ON DELETE CASCADE生效)。

检查外键是否被禁用

如果外键配置了级联但仍不生效,可能是约束被禁用了:

SELECT name, is_disabled FROM sys.foreign_keys WHERE name IN ('FK_AB_ID_A', 'FK_AB_ID_B');

如果is_disabled为1,启用约束:

ALTER TABLE AB CHECK CONSTRAINT FK_AB_ID_A;
ALTER TABLE AB CHECK CONSTRAINT FK_AB_ID_B;

2. 识别并删除表A的重复行

我们需要保留每个(Name, Surname)组合中的一行(这里以保留最小ID_A为例,你可以根据需求调整):

第一步:预览要删除的行

先执行以下SQL确认要删除的ID,避免误删:

WITH DuplicateRows AS (
    SELECT 
        ID_A,
        -- 按Name+Surname分组,给每组行编号,最小ID的行编号为1
        ROW_NUMBER() OVER (PARTITION BY Name, Surname ORDER BY ID_A) AS RowNum
    FROM 
        A
)
SELECT ID_A, Name, Surname 
FROM DuplicateRows 
JOIN A ON DuplicateRows.ID_A = A.ID_A
WHERE RowNum > 1;

第二步:执行删除操作

确认预览结果正确后,执行删除(级联删除会自动清理AB表中对应的关联记录):

WITH DuplicateRows AS (
    SELECT 
        ID_A,
        ROW_NUMBER() OVER (PARTITION BY Name, Surname ORDER BY ID_A) AS RowNum
    FROM 
        A
)
DELETE FROM DuplicateRows WHERE RowNum > 1;
  • 如果你想保留最大ID_A的行,只需将ORDER BY ID_A改为ORDER BY ID_A DESC即可。
  • 执行后,表A中每个(Name, Surname)组合只会保留一行,AB表中对应的重复关联记录也会被自动删除。

验证结果

删除完成后,执行以下SQL验证:

-- 检查表A是否还有重复行
SELECT Name, Surname, COUNT(*) AS RowCount FROM A GROUP BY Name, Surname HAVING COUNT(*) > 1;

-- 检查AB表关联是否正确(仅保留与表A现有行关联的记录)
SELECT COUNT(*) FROM AB WHERE ID_A NOT IN (SELECT ID_A FROM A);

如果第一个查询无结果,第二个查询返回0,说明操作成功。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 02:47:44