2011-01-14 43 views
1

这里是我的数据左连接TransactSQL返回我意外的结果 - 我对左连接的理解是错误的吗?

CREATE TABLE TempA ( 
    ID INT IDENTITY(1,1), 
    Msg VARCHAR(20) 
) 

INSERT INTO TempA (Msg) values ('a') 
INSERT INTO TempA (Msg) values ('b') 
INSERT INTO TempA (Msg) values ('c') 

CREATE TABLE TempB ( 
    ID INT IDENTITY(1,1), 
    Msg VARCHAR(20) 
) 

所以TempB是空的。现在我运行以下查询

select a.* 
    from TempA a 
left JOIN TempA B on a.id = b.id 

它从TempA返回3行,如预期的那样好,至今为止。让我们在上面的查询中添加一个过滤器

select a.* 
    from TempA a 
left JOIN TempA B on a.id = b.id 
    where b.msg = 'aa' 

它不返回任何行给我。我认为,因为它是一个左连接,我应该从TempA表中获得3行。我错了吗?

+2

注意:所有的例子查询是自联接。我认为你的意思是第二张桌子是“TempB”。这可以解释为什么下面的答案不起作用。 – Bill 2011-01-14 19:48:55

回答

4

通过在where子句的使用中包含b.msg过滤器,您正在将左连接转换为内连接。

select a.* from TempA a left JOIN TempB B on a.id = b.id and b.msg = 'aa' 

(概念)连接谓词情况,请从非加入行会添加回来,将有你的过滤器再次排除这些行NULLb.msg那么价值!

您可能想要查看伊茨克奔甘的Logical Query Processing Poster

+0

可否请您详细说明一下它是如何转换为内部连接的? – imak 2011-01-14 19:33:02

+0

您的where条件`b.msg ='aa'`永远不会对于由所有`b`列的连接输出的任何行为true,因为`on`条件不匹配;所以连接*有效地作为内部连接。 – araqnid 2011-01-14 19:34:43

+0

这样想,FROM子句及其所有连接都决定了一个初始数据集。然后WHERE子句过滤掉东西。如果将过滤器置于LEFT JOIN中,则会从“A”中获取所有行,以及任何“B”记录与连接条件相匹配。尝试在您的选择中包含b.msg。在你的例子中,它们都是NULL。现在将条件移至WHERE子句。 b.msg = NULL的所有记录(因为不匹配)被过滤掉。 – Bill 2011-01-14 19:46:21

1

我perfer马丁的解决方案,但另一种选择是

select a.* 
from 
    TempA a 
    left JOIN TempB B on a.id = b.id 
where b.msg = 'aa' or b.msg is null 
+0

这不会给我任何结果 – imak 2011-01-14 19:35:00

2

当使用OUTER JOIN,在WHERE款规定的标准是后应用加入。因为没有行,其中b.msg ='aa',所以不会返回任何行。

ON子句中指定的标准,该标准被应用之前的JOIN,所以b引用将只受到影响。在此示例中,b引用将返回NULL,而a引用不受影响。

4

以下是发生了什么;

你有两个表。

TempA ID Msg 
     -- --- 
     1 a 
     2 b 
     3 c 

TempB ID Msg 
     -- --- 

现在,当你这样做的加入,最初的结果看起来是这样的:

Result a.ID a.Msg b.ID b.Msg 
     ---- ----- ---- ----- 
     1 a  NULL NULL 
     2 b  NULL NULL 
     3 c  NULL NULL 

当筛选与WHERE子句查询,你过滤掉任何不具有一个b.Msg'aa'。那会过滤掉全部的记录,因为他们都有b.MsgNULL。让你有这样的:

Result a.ID a.Msg b.ID b.Msg 
     ---- ----- ---- ----- 

然后,你只选择这使得这个最终结果从TempA列:这取决于你怎么做过滤

Result a.ID a.Msg 
     ---- -----