我有两个具有相同列但具有不同行数的表,这些表具有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 回答
这也应该有效:
您的子查询不相关,并且至少返回一行 . 因此
exists
总是返回true,删除操作会尝试删除所有内容 .尝试将
not exists
与相关子查询一起使用:您也可以使用左连接执行此操作:
此外,我注意到您试图在子查询中检查所有三列是否为null . 你只需要检查一个 - 任何一个 .