我有一个非常基本的LEFT OUTER JOIN来返回来自左表的所有结果和来自一个大得多的表的一些附加信息。左表包含4935条记录,但当我left OUTER JOIN到另一个表时,记录计数明显更大。

据我所知,这是绝对的福音,一个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 JOIN将返回LEFT表与RIGHT表可能连接的所有记录。

如果有匹配,它仍然会返回所有匹配的行,因此,左边的一行匹配右边的两行将返回为两行,就像INNER JOIN一样。

编辑: 针对您的编辑,我刚刚进一步查看了您的查询,看起来您只从LEFT表返回数据。因此,如果只需要LEFT表中的数据,并且只希望LEFT表中的每一行返回一行,那么根本不需要执行JOIN,只需直接从LEFT表中执行SELECT。


左表和右表之间会是一对多的关系吗?


DATA中似乎有多行。每个SUSP的Dim_Member表。Susp_Visits行。


这不是不可能的。左表中的记录数是它将返回的最小记录数。如果右表有两条记录与左表中的一条记录相匹配,则将返回两条记录。


左表中的每个记录将返回与右表中匹配记录相同的次数——至少1次,但很容易超过1次。


如果Dim_Member中的多个(x)行与sus_visitors中的单行关联,则结果集中将有x行。


LEFT OUTER JOIN就像INNER JOIN(普通连接)一样,将为左表中的每一行返回与右表中找到的匹配数量相同的结果。因此,您可以得到很多结果-直到N x M,其中N是左表中的行数,M是右表中的行数。

它是LEFT OUTER JOIN中保证的最小结果数至少为N。


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

如果你只需要右边的任意一行

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
)

回复你的后记,这取决于你想要什么。

对于左表中的每一行,您将获得(可能)多行,因为连接条件有多个匹配项。如果希望总结果的行数与查询左侧的行数相同,则需要确保连接条件是1对1匹配。

或者,根据您的实际需要,您可以使用聚合函数(例如,如果您只想从右侧部分获得字符串,则可以为左侧行生成一个由逗号分隔的右侧结果字符串的列。

如果您只查看来自外部连接的1或2列,您可能会考虑使用标量子查询,因为您将保证得到1个结果。


如果在包含左外连接的查询的“右侧”表中有where子句,请注意… 如果右侧没有满足where子句的记录,那么“左侧”表的相应记录将不会出现在查询....的结果中


由于左边的表包含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

您的查询将返回比左侧表(SUSP)更多行的唯一方法。在你的例子中是sus_visitors),是条件(sus_sus_visitors。MemID = DATA.Dim_Member. membershipnum)匹配右边表DATA.Dim_Member中的多行。因此,DATA中有多行。其中DATA.Dim_Member.MembershipNum的值相同。你可以通过执行下面的查询来验证:

选择DATA.Dim_Member。MembershipNum, count(DATA. dim_member .MembershipNum) from DATA。根据DATA.Dim_Member.MembershipNum指定成员组


简单地说,LEFT OUTER JOIN是每个连接键内的笛卡尔积,以及左表中不匹配的行 (例如,对于每个key_x,在table_L中有N条记录,在table_R中有M条记录,如果M>0,结果将有N*M条记录,或者如果M=0,结果将有N条记录)