Jay*_*lde 146 sql t-sql sql-server sql-server-2005
我有一个非常基本的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
Run Code Online (Sandbox Code Playgroud)
也许我在语法上犯了一个错误,或者我对LEFT OUTER JOIN的理解是不完整的,希望有人可以解释这是如何发生的?
后记
感谢你们给出了很好的答案,我对LEFT OUTER JOINS的理解现在要好得多,但是有人可以提出一种方法可以修改这个查询,这样我只能获得与左表中存在的记录一样多的记录吗?
此查询纯粹是为了生成报告,而重复的匹配只是简单地混淆了问题.
/后记
Rob*_*Day 167
LEFT OUTER JOIN将尽可能返回与RIGHT表连接的LEFT表中的所有记录.
如果有匹配,它仍将返回匹配的所有行,因此,LEFT中与RIGHT中的两行匹配的一行将返回为两个ROWS,就像INNER JOIN一样.
编辑:为了响应您的编辑,我只是进一步查看您的查询,看起来您只是从LEFT表返回数据.因此,如果您只需要来自LEFT表的数据,并且您只希望为LEFT表中的每一行返回一行,那么您根本不需要执行JOIN,只需直接从LEFT表执行SELECT.
And*_*wis 105
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
Run Code Online (Sandbox Code Playgroud)
结果:
1,null
2,2
2,2
3,null
4,null
Run Code Online (Sandbox Code Playgroud)
Chr*_*lls 11
在回复您的后记时,这取决于您的需求.
您可以为左表中的每一行获取(可能)多行,因为连接条件有多个匹配项.如果您希望总结果的行数与查询左侧的行数相同,则需要确保连接条件与1对1匹配.
或者,根据您的实际需要,您可以使用聚合函数(例如,如果您只需要来自右侧部分的字符串,则可以生成一个列,该列是右侧结果的逗号分隔字符串,用于该左侧行.
如果您只查看外部联接中的1或2列,则可以考虑使用标量子查询,因为您将获得1个结果.
就像INNER JOIN(普通连接)一样,LEFT OUTER JOIN将为左表中的每一行返回尽可能多的结果,因为它在右表中找到了许多匹配.因此,您可以获得大量结果 - 最多N x M,其中N是左表中的行数,M是右表中的行数.
在LEFT OUTER JOIN中,始终保证最小结果数至少为N.
如果您只需要右侧的任何一行
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
Run Code Online (Sandbox Code Playgroud)
要不就
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
)
Run Code Online (Sandbox Code Playgroud)