Sql 什么时候将内部联接左联接表/
我今天遇到了以下代码Sql 什么时候将内部联接左联接表/,sql,sql-server,Sql,Sql Server,我今天遇到了以下代码 SELECT StaffGroup.* FROM StaffGroup LEFT OUTER JOIN StaffByGroup ON StaffByGroup.StaffGroupId = StaffGroup.StaffGroupId INNER JOIN StaffMember ON StaffMember.StaffMemberId = StaffByGroup.StaffMemberId WHERE StaffByGroup.StaffGroupId
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
表与StaffMember
表内连接
我认为内部联接正在尝试筛选出存在于StaffGroup
和StaffByGroup
中但不存在于StaffMember
中的记录
但事实并非如此。查询不返回任何记录
我在理解查询的逻辑时是否遗漏了什么?您是否曾经对查询前面部分中与左联接一起使用的表使用过内部联接?由于您的
where子句,您将获得0条记录
where StaffByGroup.StaffGroupId is null
left join
链接tbl B中包含的来自tbl A的所有记录,并且由于您已将StaffGROUPID
指定为键,然后在键中查找null
值,因此100%清楚的是,您将不会得到任何结果由于where子句,您将获得0条记录
where StaffByGroup.StaffGroupId is null
left join
链接tbl B中包含的tbl A中的所有记录,并且由于您指定了StaffGROUPID
作为密钥,然后在密钥中查找null
值,因此100%清楚的是,您将不会得到任何结果实际上您缺少一个概念:
主表StaffGroup
正与StaffByGroup
表左连接,然后创建一个虚拟表
sayVT1
,其中包含来自StaffGroup的所有记录,并根据on
谓词中的匹配/筛选条件匹配来自StaffByGroup的记录。然后不是StaffByGroup表但是基于
谓词上的
中的匹配/筛选条件,这个VT1
正在与StaffMember
表进行内部连接。
因此,基本上,内部连接是试图从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
实际上,您缺少一个概念:
主表StaffGroup
正与StaffByGroup
表左连接,然后创建一个虚拟表
sayVT1
,其中包含来自StaffGroup的所有记录,并根据on
谓词中的匹配/筛选条件匹配来自StaffByGroup的记录。然后不是StaffByGroup表但是基于
谓词上的
中的匹配/筛选条件,这个VT1
正在与StaffMember
表进行内部连接。
因此,基本上,内部连接是试图从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
这个查询看起来有根本性的缺陷——我猜最初的意图是
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的组(与StaffMember的内部联接过滤掉StaffByGroup中没有匹配行的行,可能是因为它们之间没有外键)这个查询看起来有根本性的缺陷——我猜最初的目的是
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的组(与StaffMember的内部联接会从StaffByGroup中筛选出StaffMember中没有匹配行的行-可能是因为它们之间不存在外键)如果删除where
子句,它会返回记录吗?是的。如果删除WHERE子句,它将返回所有三个表中存在的记录。如果删除WHERE
子句,它是否返回记录?是。如果我删除WHERE子句,它将返回所有三个表中存在的记录。可以安全地说查询是错误的,需要更正吗?实际上,这是现有的代码,我正在对其进行反向工程。这实际上取决于您的确切需求。我提出了一个示例场景。希望有帮助……)可以肯定地说,这个问题是错误的,需要纠正吗?实际上,这是现有的代码,我正在对其进行反向工程。这实际上取决于您的确切需求。我提出了一个示例场景。希望有帮助……)我不认为这与最初的查询有什么不同。它不会返回结果,因为StaffByGroup.StaffGroupId为NULL时没有记录,这与原始查询非常不同。原始查询无法返回任何结果,因为内部联接只允许StaffMember/StaffByGroup中具有匹配行的结果,并且这些行随后会被WHERE子句删除。我修改后的查询首先返回StaffGroup中的所有行以及StaffByGroup/StaffMember的可选值,然后删除那些没有匹配StaffMember/StaffByGroup的行。是的,您是正确的。你觉得呢,也许是斯塔夫曼