LEFT JOIN根据WHERE条件的位置给出不同的数据集

HHH*_*HHH 5 sql t-sql sql-server sql-server-2008 sql-server-2012

请参阅以下3个计数,只是为了简要介绍一下表格数据.所有skCitizen[dbo].[LUEducation]存在于[dbo].[LUCitizen]

SELECT  COUNT(*) FROM   [dbo].[LUCitizen] --115000 ROWS
SELECT  COUNT(*) FROM   [dbo].[LUEducation]  --201846 ROWS

SELECT  COUNT(*) --212695 ROWS
FROM    [dbo].[LUCitizen] C
LEFT JOIN   [dbo].[LUEducation] E
ON      C.skCitizen = E.skCitizen

SELECT  COUNT(*) FROM   [dbo].[LUEducation] WHERE skSchool = 24417 --4 ROWS
Run Code Online (Sandbox Code Playgroud)

请参阅以下2个查询,

SELECT  C.skCitizen,E.skCitizen
FROM    [dbo].[LUCitizen] C
LEFT JOIN   [dbo].[LUEducation] E
ON      C.skCitizen = E.skCitizen
WHERE   E.skSchool = 24417
--4 ROWS

SELECT  C.skCitizen,E.skCitizen
FROM    [dbo].[LUCitizen] C
LEFT JOIN   (SELECT * FROM [dbo].[LUEducation] WHERE skSchool = 24417) E
ON      C.skCitizen = E.skCitizen
--115000 ROWS
Run Code Online (Sandbox Code Playgroud)

在最后2个查询中,对我来说令人困惑的查询是第一个.在那里,我期待115000 rows,但只4 rows显示.根据我的理解,[dbo].[LUCitizen]将显示Full rows from ,然后[dbo].[LUEducation]将有4行来自LEFTJoined.

为什么2个查询不同?

请原谅,如果这是一个重复的问题.

Gor*_*off 8

当你这样做:

SELECT  C.skCitizen,E.skCitizen
FROM    [dbo].[LUCitizen] C
LEFT JOIN   [dbo].[LUEducation] E
ON      C.skCitizen = E.skCitizen
WHERE   E.skSchool = 24417;
Run Code Online (Sandbox Code Playgroud)

您正在转动left joininner join,因为E.skSchoolNULL针对非匹配行.将条件放在a中的第二个表的正确方法left join是使用以下on子句:

SELECT  C.skCitizen,E.skCitizen
FROM    [dbo].[LUCitizen] C
LEFT JOIN   [dbo].[LUEducation] E
ON      C.skCitizen = E.skCitizen AND E.skSchool = 24417;
Run Code Online (Sandbox Code Playgroud)


And*_*mar 3

如果left join未能在 中找到匹配项E,则列会E收到一个null值。然后where条款:

E.skSchool = 24417
Run Code Online (Sandbox Code Playgroud)

变成:

null = 24417
Run Code Online (Sandbox Code Playgroud)

这不是真的。所以它会过滤掉所有行。