我有一个非常基本的LEFT OUTER JOIN来返回左表中的所有结果以及来自更大表的一些附加信息。左表包含4935条记录,但当我将其连接到另一个表时,记录计数明显更大。
据我所知,LEFT OUTER JOIN将返回左表中所有记录,右表中的匹配记录和无法匹配的任何行的空值,这是绝对的福音,因此这是我的理解它应该是不可能返回比左表中存在的更多的行,但它发生的一切都是一样的!
SQL查询如下:
SELECT SUSP.Susp_Visits.SuspReason, SUSP.Susp_Visits.SiteID
FROM SUSP.Susp_Visits LEFT OUTER JOIN
DATA.Dim_Member ON SUSP.Susp_Visits.MemID = DATA.Dim_Member.MembershipNum
也许我在语法上犯了一个错误,或者我对LEFT OUTER JOIN的理解是不完整的,希望有人可以解释这是如何发生的?
后记
感谢您提供了很好的答案,我对LEFT OUTER JOINS的理解现在要好得多,但是有人可以提出一种方法可以修改此查询,这样我只能获得与左表中存在的记录一样多的记录吗?
此查询纯粹是为了生成报告,重复的匹配只会让事情变得混乱。
/后记
答案 0 :(得分:151)
LEFT OUTER JOIN将尽可能返回与RIGHT表连接的LEFT表中的所有记录。
如果有匹配,它仍将返回匹配的所有行,因此,LEFT中与RIGHT中的两行匹配的一行将返回为两个ROWS,就像INNER JOIN一样。
编辑: 为了回应您的编辑,我只是进一步查看了您的查询,看起来您只是从LEFT表返回数据。因此,如果您只需要来自LEFT表的数据,并且您只希望为LEFT表中的每一行返回一行,那么您根本不需要执行JOIN,只需直接从LEFT表执行SELECT。
答案 1 :(得分:93)
Table1 Table2
_______ _________
1 2
2 2
3 5
4 6
SELECT Table1.Id, Table2.Id FROM Table1 LEFT OUTER JOIN Table2 ON Table1.Id=Table2.Id
结果:
1,null
2,2
2,2
3,null
4,null
答案 2 :(得分:27)
这不是不可能的。左表中的记录数是它将返回的最小记录数。如果右表有两条记录与左表中的一条记录匹配,则它将返回两条记录。
答案 3 :(得分:10)
在回复您的附言时,这取决于您的需求。
左表中的每一行都有(可能)多行,因为连接条件有多个匹配项。如果您希望总结果的行数与查询左侧的行数相同,则需要确保您的加入条件导致一对一匹配。
或者,根据您的实际需要,您可以使用聚合函数(例如,如果您只需要来自右侧部分的字符串,则可以生成一个列,该列是左侧行的右侧结果的逗号分隔字符串。
如果您只查看外部联接中的1列或2列,则可以考虑使用标量子查询,因为您将获得1个结果。
答案 4 :(得分:8)
左表中的每条记录将返回与右表中匹配记录一样多的次数 - 至少为1,但可能很容易超过1。
答案 5 :(得分:7)
LEFT OUTER JOIN就像INNER JOIN(普通连接)一样,将为左表中的每一行返回尽可能多的结果,因为它在右表中找到了许多匹配。因此,您可以获得大量结果 - 最多N x M,其中N是左表中的行数,M是右表中的行数。
在LEFT OUTER JOIN中始终保证最小结果数至少为N.
答案 6 :(得分:6)
它可能是左右表之间的一对多关系吗?
答案 7 :(得分:6)
如果在包含左外连接的查询的“右侧”表中有where子句,请注意... 如果您在右侧没有满足where子句的记录,那么“左侧”表的相应记录将不会出现在您的查询结果中....
答案 8 :(得分:4)
如果您只需要右侧的任何一行
SELECT SuspReason, SiteID FROM(
SELECT SUSP.Susp_Visits.SuspReason, SUSP.Susp_Visits.SiteID, ROW_NUMBER()
OVER(PARTITION BY SUSP.Susp_Visits.SiteID) AS rn
FROM SUSP.Susp_Visits
LEFT OUTER JOIN DATA.Dim_Member ON SUSP.Susp_Visits.MemID = DATA.Dim_Member.MembershipNum
) AS t
WHERE rn=1
或只是
SELECT SUSP.Susp_Visits.SuspReason, SUSP.Susp_Visits.SiteID
FROM SUSP.Susp_Visits WHERE EXISTS(
SELECT DATA.Dim_Member WHERE SUSP.Susp_Visits.MemID = DATA.Dim_Member.MembershipNum
)
答案 9 :(得分:1)
似乎每个SUSP.Susp_Visits行的DATA.Dim_Member表中有多行。
答案 10 :(得分:1)
如果Dim_Member中的多个(x)行与Susp_Visits中的单个行相关联,则结果集中将有x行。
答案 11 :(得分:0)
由于左表包含 4935 条记录,我怀疑您希望结果返回 4935 条记录。试试这个:
create table table1
(siteID int,
SuspReason int)
create table table2
(siteID int,
SuspReason int)
insert into table1(siteID, SuspReason) values
(1, 678),
(1, 186),
(1, 723)
insert into table2(siteID, SuspReason) values
(1, 678),
(1, 965)
select distinct t1.siteID, t1.SuspReason
from table1 t1 left join table2 t2 on t1.siteID = t2.siteID and t1.SuspReason = t2.SuspReason
union
select distinct t2.siteID, t2.SuspReason
from table1 t1 right join table2 t2 on t1.siteID = t2.siteID and t1.SuspReason = t2.SuspReason