这是另一个答案,逐步解释了查询中发生的情况。让我们查询 #2:
DELETE FROM Temp
WHERE EXISTS
(
SELECT 1
FROM Temp AS IL2
WHERE Temp.A = IL2.A
AND Temp.B = 5
AND IL2.B = 1
);
该语句应该在表 Temp 中查找记录并删除它们。所以让我们从第一条记录开始,看看它是否符合 where 子句中给出的条件:
第 1 行:A=1,B=1
我们在同一个表中寻找存在,我们称之为 IL2(就像它是不同的表一样)。因此,每当我们引用我们可能想要删除或不删除的刚刚读取的记录时,我们使用限定符 Temp,并且我们读取表 IL2 记录的记录,以便将它们与 Temp 记录进行比较。所以让我们看看是否找到匹配项:
一个 |乙|温度.A = IL2.A? |温度 B = 5? | IL2.B = 1?
--+---+--------------------------------+---------- ---------+------------
1 | 1 |是的,两条记录的 A=1。 |不,Temp.B 为 1。是的。
1 | 5 |是的,两条记录的 A=1。 |不,Temp.B 为 1。不,是5。
2 | 2 |不,Temp.A 为 1,IL2.A 为 2。不,Temp.B 为 1。不,是2。
如你所见,Temp.B = 5?总是错误的(并且总是正确的,因为我们查看了第二个记录行#2),因为尽管条件在 EXISTS 子查询中,但它实际上是指经受考验的记录。这就是为什么我建议将此标准移到 EXISTS 子句之外以提高可读性。此查询 100% 等效,但更易于阅读:
DELETE FROM Temp
WHERE B = 5
AND EXISTS
(
SELECT 1
FROM Temp AS IL2
WHERE IL2.A = Temp.A
AND IL2.B = 1
);
现在让我们看看这个查询。我们再次从 Temp 中读取第一行。 B 为 1,因此不匹配 WHERE B = 5。不满足条件,记录不会被删除。
下一条记录(第 2 行)。 B = 5。好吧,让我们看看exists子句并再次检查记录:
一个 |乙|温度.A = IL2.A? | IL2.B = 1?
--+---+--------------------------------+---------- --
1 | 1 |是的,两条记录的 A=1。 |是的。
1 | 5 |是的,两条记录的 A=1。 |不,是5。
2 | 2 |不,Temp.A 为 1,IL2.A 为 2。不,是2。
啊哈。第一条记录匹配,因此满足 EXISTS 条件。 (DBMS 必须找到至少一个匹配项。一旦找到匹配项,它就不必读取剩余的记录。所以我们可以在找到第 1 行作为匹配项之后停止。)所有条件都是 TRUE;调查的 Temp 记录(第 2 行)将被删除。
现在到最后一条记录。 B 是 2,所以 WHERE B = 5 不匹配。不满足条件,记录不会被删除。
我希望这能阐明 EXISTS 的工作原理。 (至于“选定”数据:在 EXISTS 中选择什么并不重要;这三个都一样:where exists (select 1 from ...)、where exists (select * from ...)、where exists (select 'yes, there exists a row' from ...)。)