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



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

表1 是原始表,表 2 是由于删除了数据而具有较少行的更新表。我有一个 SELECT 语句,它返回表 1 中的行,但不返回表 2 中的行;然而,当我使用 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 查询时,将表 2 中不在表 1 中的所有行插入表 1,它也工作正常。

所以我不知道我在 DELETE 语句上搞砸了哪里。

我尝试使用:

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

但是我收到一个错误,说使用存在。这在访问数据库中使用,所以我想与sql服务器相同的规则适用。

提前感谢任何帮助。

您的子查询不相关,并且返回至少一行。因此,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。您只需要检查一个 - 任何一个。

这也应该有效:

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

最新更新