SQL在JOIN条件中使用过滤器与WHERE子句中的过滤器保持连接

The*_*ler 4 sql t-sql sql-server join outer-join

我在工作中重构一些sql,偶然发现了一些我不确定如何解释的东西.我认为有两个查询会产生相同的结果,但不会,我不知道为什么.

查询如下:

select *
from TableA as a
left join TableB b on a.id = b.id and b.status in (10, 100)

select *
from TableA as a
left join TableB b on a.id = b.id
where b.status is null or b.status in (10, 100)
Run Code Online (Sandbox Code Playgroud)

什么时候这些不会返回相同的结果?

Dhr*_*shi 5

与Where条件的最大区别b.status is null or b.status in (10, 100) 在于b.status为1以及b.id = a.id

在第一个查询中,您仍将获得表A中的行,其中相应的B部分为NULL,因为On条件未完全满足.在第二个查询中,您将在JOIN中获取a和b表中的行,这些行将在where子句中丢失.


Paw*_*Dyl 5

让我举一个例子:

SELECT * INTO #A FROM (VALUES 
(1),(2),(3),(4)) T(id)

SELECT * INTO #B FROM (VALUES
(1,NULL),
(2,1),
(3,10)) T(id,status)

select *
from #A as a
left join #B b on a.id = b.id and b.status in (10, 100)

select *
from #A as a
left join #B b on a.id = b.id
where b.status is null or b.status in (10, 100)
Run Code Online (Sandbox Code Playgroud)

结果

id          id          status
----------- ----------- -----------
1           NULL        NULL
2           NULL        NULL
3           3           10
4           NULL        NULL

id          id          status
----------- ----------- -----------
1           1           NULL
3           3           10
4           NULL        NULL
Run Code Online (Sandbox Code Playgroud)

最终回应:

  1. 如果状态不在(10,100)中,则LEFT JOIN应用NULL
  2. 如果状态为NULL,则LEFT JOIN也适用NULL,谓词无效