首页 文章

DELETE子句删除的行比SELECT子查询返回的行数多

提问于
浏览
0

我有两个具有相同列但具有不同行数的表,这些表具有3列复合主键 .

table1是原始表,table2是更新的表,由于数据被删除,因此行数较少 . 我有一个SELECT语句,返回table1中的行,但不返回table2中的行;然而,当我使用WHERE EXISTS将SELECT语句作为子查询放在DELETE子句中时,它想要删除表1中的所有行,而不仅仅是子查询中的行 .

码:

DELETE FROM table1
WHERE EXISTS(
SELECT t1.*
FROM table1 AS t1 LEFT JOIN table2 AS t2
ON (t1.compositekey1 = t2.compositekey1)
AND (t1.compositekey2 = t2.compositekey2)
AND (t1.compositekey3 = t2.compositekey3)
WHERE (t2.compositekey1 IS NULL) AND 
(t2.compositekey2 IS NULL) AND (t2.compositekey3 IS 
NULL)
);

我测试子查询作为一个独立的SELECT查询,它返回110行,正确的数量,但当放入上面的DELETE查询时,它想要删除所有9600行 . 我的印象是,WHERE EXISTS应该只删除子查询返回的虚拟表中的行 .

当我使用反向查询作为INSERT查询时,将table2中不在table1中的所有行插入到表1中,它也可以正常工作 .

所以我不知道我在哪里弄乱DELETE语句 .

我试着用:

WHERE t1.compositekey1, t1.compositekey2, t1.compositekey3 IN (......)

但我得到一个错误说使用EXISTS . 这是在访问数据库中使用,所以我猜相同的规则适用于sql server .

在此先感谢您的帮助 .

2 回答

  • 3

    这也应该有效:

    DELETE
    FROM
        table1
    WHERE
        EXISTS
        (
            SELECT
                *
            FROM
                table2
            WHERE
                table1.compositekey1 = table2.compositekey1
            AND table1.compositekey2 = table2.compositekey2
            AND table1.compositekey3 = table2.compositekey3 );
    
  • 0

    您的子查询不相关,并且至少返回一行 . 因此 exists 总是返回true,删除操作会尝试删除所有内容 .

    尝试将 not exists 与相关子查询一起使用:

    delete
    from table1 t1
    where not exists (
            select 1
            from table2 t2
            where t1.compositekey1 = t2.compositekey1
                and t1.compositekey2 = t2.compositekey2
                and t1.compositekey3 = t2.compositekey3
            );
    

    您也可以使用左连接执行此操作:

    delete t1
    from table1 t1
    left join table2 t2 on t1.compositekey1 = t2.compositekey1
        and t1.compositekey2 = t2.compositekey2
        and t1.compositekey3 = t2.compositekey3
    where t2.compositekey1 is null;
    

    此外,我注意到您试图在子查询中检查所有三列是否为null . 你只需要检查一个 - 任何一个 .

相关问题