我今天遇到了以下代码。
SELECT StaffGroup.*
FROM StaffGroup
LEFT OUTER JOIN StaffByGroup
ON StaffByGroup.StaffGroupId = StaffGroup.StaffGroupId
INNER JOIN StaffMember
ON StaffMember.StaffMemberId = StaffByGroup.StaffMemberId
WHERE StaffByGroup.StaffGroupId IS NULL
主表StaffGroup
正在与StaffByGroup
表进行LEFT JOIN,然后StaffByGroup
表正在与StaffMember
表进行内联。
我认为INNER JOIN正在尝试过滤掉StaffGroup
和StaffByGroup
中存在但StaffMember
中不存在的记录。
但这不是它的工作方式。查询不会返回任何记录。
我在理解查询逻辑时遗漏了什么?你有没有使用INNER JOIN和一个在查询的前面部分与LEFT JOIN一起使用的表?
答案 0 :(得分:2)
其实你错过了一个概念:
主表StaffGroup
正在LEFT Joined
与StaffByGroup
表,然后创建virtual table
说VT1
,其中包含来自StaffGroup的所有记录以及来自StaffByGroup的匹配记录ON
谓词中的匹配/过滤条件。那么不是StaffByGroup表,而是VT1
根据INNER Joined
中的匹配/过滤条件,StaffMember
表ON
谓语。
所以基本上内部联接试图从StaffGroup过滤掉那些没有StaffMemberId的StaffByGroup记录。
添加where条件会添加最终过滤器,例如从上面所有连接创建的最终虚拟表中删除所有没有StaffGroupId的记录,而这些记录又可能会删除VT1
中收集的所有行将为StaffGroupId提供一些价值。
要获取StaffGroup中没有StaffGroupId的所有记录以及StaffMember中所有此类记录的详细信息,您可以在ON谓词中添加条件:
SELECT StaffGroup.*
FROM StaffGroup
LEFT OUTER JOIN StaffByGroup
ON StaffByGroup.StaffGroupId = StaffGroup.StaffGroupId and StaffByGroup.StaffGroupId IS NULL
INNER JOIN StaffMember
ON StaffMember.StaffMemberId = StaffByGroup.StaffMemberId
答案 1 :(得分:1)
由于您的where clause
where StaffByGroup.StaffGroupId is null
left join
链接来自tbl A的所有记录,这些记录包含在tbl B中,因为您已指定StaffGROUPID
作为密钥,然后在密钥中查找Nulls
个值, 100%明确表示你最终没有结果
答案 2 :(得分:1)
这个查询看起来存在根本缺陷 - 我想最初的目的是
SELECT StaffGroup.*
FROM StaffGroup
LEFT OUTER JOIN
(SELECT * FROM StaffByGroup
INNER JOIN StaffMember
ON StaffMember.StaffMemberId = StaffByGroup.StaffMemberId) StaffByGroup
ON StaffByGroup.StaffGroupId = StaffGroup.StaffGroupId
WHERE StaffByGroup.StaffGroupId IS NULL
返回StaffGroup中没有分配给他们的现有人员的所有组(带有StaffMember的INNER JOIN过滤掉StaffByGroup中没有StaffMember中匹配行的那些行 - 可能是因为他们之间不存在外键)