Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 什么时候将内部联接左联接表/_Sql_Sql Server - Fatal编程技术网

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
左连接,然后创建一个
虚拟表
say
VT1
,其中包含来自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
左连接,然后创建一个
虚拟表
say
VT1
,其中包含来自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的行。是的,您是正确的。你觉得呢,也许是斯塔夫曼