2013-11-27 74 views
2

今天我在下面的代码中遇到过。你什么时候INNER JOIN LEFT JOINed表/

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表,然后StaffByGroup表正被INNER加入了与StaffMember表。

我认为INNER JOIN试图过滤出StaffGroupStaffByGroup中存在的记录,但StaffMember中不存在。

但这不是它是如何工作的。该查询不返回任何记录。

我在理解查询逻辑时错过了一些东西吗?你有没有使用INNER JOIN和在查询的早期部分使用过LEFT JOIN的表?

+0

如果删除where子句,它是否返回记录? – Szymon

+0

是的。如果我删除WHERE子句,它将返回所有三个表中存在的记录。 – jags

回答

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是不”已分配给他们(INNER JOIN与StaffMember过滤掉那些StaffByGroup行没有匹配的行StaffMember现有staffmembers所有群体 - 可能是因为它们之间不存在外键)

+0

我不认为这是从原来的查询不同。并且它没有返回结果,因为没有记录'WHERE StaffByGroup.StaffGroupId IS NULL' – VitaliyG

+0

@VitaliyG这与原始查询非常不同。原始查询*无法返回任何结果,因为内部联接只允许在StaffMember/StaffByGroup中具有匹配行的结果,然后这些行将由WHERE子句删除。我修改后的查询首先返回StaffGroup中的* all *行以及StaffByGroup/StaffMember的可选值,然后删除那些没有匹配StaffMember/StaffByGroup的行。 –

+0

是的你是对的。你认为什么,也许StaffMember可以简单地离开加入,而不是使用子选择。 – VitaliyG

1

你得到,因为你where clause

where StaffByGroup.StaffGroupId is null 

left join链接0条记录都来自TBL A,其包含在TBL B和你既然已指定StaffGROUPID为您的密钥,然后寻找Nulls值的记录在你的钥匙,其100%的清楚,你最终会没有结果

2

其实你缺少一个概念: 主表StaffGroup正在LEFT JoinedStaffByGroup表和T母鸡这将创建一个virtual tableVT1与StaffGroup从StaffByGroup所有记录和匹配记录基于在ON predicate.Then你匹配/过滤条件没有StaffByGroup表,但这个VT1是基于ON谓词匹配/过滤条件是INNER JoinedStaffMember表。 所以基本上内连接试图从StaffGroup中筛选出那些记录,因此StaffByGroup没有StaffMemberId。 添加您的where条件会添加一个类似于由上述所有联接创建的最终虚拟表的最终过滤器,删除所有没有StaffGroupId的记录,这样可能会删除VT1中收集的所有行,因为它们都将具有一些值为StaffGroupId。

要想从StaffGroup它们没有什么可StaffGroupId与StaffMember细节所有这些记录一起,你可以在谓词添加条件的所有记录为:

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 
+0

可以安全地说,查询是错误的,需要更正吗?其实这是现有的代码,我正在对其进行逆向工程。 – jags

+0

这实际上取决于你有什么确切的要求。我提出了一个示例场景。希望这有助于..:) – Deepshikha

相关问题