Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 在联接中包含where子句的左联接_Sql Server - Fatal编程技术网

Sql server 在联接中包含where子句的左联接

Sql server 在联接中包含where子句的左联接,sql-server,Sql Server,假设我们有以下表格结构: DECLARE @Person TABLE ( PersonId INT, Name VARCHAR(50) ) DECLARE @Address TABLE ( AddressId INT IDENTITY(1,1), PersonId INT ) 我们插入两个人的记录: INSERT INTO @Person (PersonId, Name) VALUES (1, 'John Doe') INSERT INTO @Person (

假设我们有以下表格结构:

DECLARE @Person TABLE
(
    PersonId INT,
    Name VARCHAR(50)
)

DECLARE @Address TABLE
(
    AddressId INT IDENTITY(1,1),
    PersonId INT
)
我们插入两个人的记录:

INSERT INTO @Person (PersonId, Name) VALUES (1, 'John Doe')
INSERT INTO @Person (PersonId, Name) VALUES (2, 'Jane Doe')
但是我们只为
John

INSERT INTO @Address (PersonId) VALUES (1)
如果我执行以下查询,我会得到不同的结果

SELECT * 
FROM @Person p
 LEFT JOIN @Address a
    ON p.PersonId = a.PersonId AND a.PersonId IS NULL

VS



为什么查询返回不同的结果?

第一个查询不符合您的任何条件。因此,它显示了
@Person
表中的所有结果(典型的
左连接
)。其中,与第二个查询一样,
Where
子句应用于
join
之后。因此,它显示了正确的结果。

首先:

Person
获取所有记录(两个),并从
Address
加入
0
记录,因为地址中没有
PersonID=NULL
。之后,不再应用其他过滤器。您可以看到
Person

第二:


Person
获取所有记录(两条),其中一条记录以
ID=1加入到
Address
。在此之后,您的
WHERE
过滤器将被应用,并且其中一个joined
ID=1的记录将消失。

ON子句定义了要从两个表中显示的所有匹配行。 WHERE子句实际上过滤行

在第一个查询中,它返回2行,因为LEFT JOIN返回左表中的所有行,而不考虑右表中的匹配


第二个查询返回1行,因为对于PersonId=1,@Address表包含匹配的记录,因此a.PersonId不为NULL

养成习惯,从
Where
条件中读取SQL查询,然后查看
连接,这将使您对正在发生或将要返回的内容有更清晰的含义/理解

在这种情况下,您所说的
中a.PersonId为NULL
必须出现
选择
部分,并且必须使用以下
加入
标准加入

这就是机器读取查询的方式,因此会产生不同的结果集


相反,在没有where子句的情况下,左表(p)上的结果不必存在于(a)上,但同时(a)上的结果必须为null,但可能已经不存在了。此时您的SQL已经被搞糊涂了。

它变成了一个内部联接:因为personID上的
左联接确实产生了一个匹配项,并且personID在该行中不为NULL。
 PersonId | Name     | AddressId | PersonId
 1        | John Doe | NULL      | NULL
 2        | Jane Doe | NULL      | NULL
SELECT * 
FROM @Person p
 LEFT JOIN @Address a
    ON p.PersonId = a.PersonId
WHERE a.PersonId IS NULL
 PersonId | Name     | AddressId | PersonId
 2        | Jane Doe | NULL      | NULL