首页 > 解决方案 > 处理 SQL ON EXISTS 语句

问题描述

我有一个我不明白的 Transact SQL 问题。

我有 2 个表 tblMedewerker2 和 tblMedewerker3。

tblMedewerker2 获得了员工编号的以下值:129、143,144,145,146,147,169。

tblMedewerker3 获得了员工编号的以下值:129、143,144,145,146,147、166,167,168。

它们分别包含 7 行和 9 行,因此值是唯一的。

以下查询产生 63 行:

select  
        a.employeenumber as emp_a
        , b.employeenumber as emp_b 
        , isnull(a.employeenumber, b.employeenumber) as single_employeenumber
from tblMedewerker2 a
full join
tblMedewerker3 b
on exists
(
select a.employeenumber from tblMedewerker2
union
select b.employeenumber from tblmedewerker3
)

而此查询产生 10 行:

select  
        a.employeenumber as emp_a
        , b.employeenumber as emp_b 
        , isnull(a.employeenumber, b.employeenumber) as single_employeenumber
from tblMedewerker2 a
full join
tblMedewerker3 b
on exists
(
select a.employeenumber from tblMedewerker2
intersect
select b.employeenumber from tblmedewerker3
)

为什么第一个查询会将 SQL 变成某种 CROSS JOIN ?

我会说存在只是返回一个 TRUE 或 FALSE。那么为什么两个查询中的记录数不同呢?

谢谢 !Rgds BB

标签: tsqlunionexistsintersect

解决方案


它归结为所有 JOIN 的工作方式。让我们考虑一个简单的 INNER JOIN

SELECT a.id, b.id
FROM
a
INNER JOIN
b 
ON a.id = b.id

这就是说“将每一行与另一个表中的每一行进行比较。当 ON 条件为真时,将连接在一起的行包含在结果中”

现在考虑以下有效查询:

SELECT a.id, b.id
FROM
a
INNER JOIN
b 
ON 1==1

同样,它的工作方式如上所述。“将每一行与另一个表中的每一行进行比较。当 ON 条件为真时,将连接在一起的行包含在结果中”。在这种情况下,所有比较的 ON 条件都为真。

因此,如果左表有 7 行,右表有 9 行,您将得到 63 行。(我把它放在 SQL Fiddle 中供您自己查看:http ://sqlfiddle.com/#!18/87097/17 )

ON EXISTS在第一个查询中的陈述总是正确的,因为您要加入的表中的任何行都可以在UNION. 它与我上面的 1==1 示例非常相似。它FULL JOIN在第一个查询中的事实并不重要。如果它是LEFT JOINor INNER JOINorFULL JOIN它将返回 63 行。

在您的第二个查询中,ON 条件仅在有限的一组情况下为真:当被评估的行恰好位于两个表的交集时。

作为旁注。您的第二个查询可以简化为比较employeeNumbers 的常用ON 子句。这是因为 ON 子句实际上是取两个表的交集。您可以将第二个查询编写为:

select  
        a.employeenumber as emp_a
        , b.employeenumber as emp_b 
        , isnull(a.employeenumber, b.employeenumber) as single_employeenumber
from tblMedewerker2 a
full join
tblMedewerker3 b
on a.employeeNumber = b.employeeNumner

推荐阅读