左连接没有做我期望的事情

时间:2014-07-14 21:25:38

标签: tsql sql-server-2008-r2 left-join

完全困惑,我已经在这工作了2个小时

我认为加入左侧的限制很荣幸

在这个查询中,我得到[docSVsys]。[visibility] 1和<> 1
我认为这会将[docSVsys]。[visibility]限制为1

select top 1000 
       [docSVsys].[sID], [docSVsys].[visibility] 
      ,[Table].[sID],[Table].[enumID],[Table].[valueID] 
  from [docSVsys]  with (nolock) 
  left Join [DocMVenum1] as [Table] with (nolock) 
    on [docSVsys].[visibility] in (1)
   and [Table].[sID] = [docSVsys].[sID]
   and [Table].[enumID] = '140' 
   and [Table].[valueID] in (1,7) 

这有效

select top 1000 
       [docSVsys].[sID], [docSVsys].[visibility] 
      ,[Table].[sID],[Table].[enumID],[Table].[valueID] 
  from [docSVsys]  with (nolock) 
  left Join [DocMVenum1] as [Table] with (nolock) 
    on [Table].[sID] = [docSVsys].[sID]
   and [Table].[enumID] = '140' 
   and [Table].[valueID] in (1,7)
 where [docSVsys].[visibility] in (1)

我只是度过了一个非常休息的日子,因为我在脑海里想到了左边是否尊重了加入

2 个答案:

答案 0 :(得分:1)

SELECT *
FROM A
LEFT JOIN B ON Condition

相当于

 SELECT *
 FROM A
 CROSS JOIN B
 WHERE Condition
UNION ALL
 SELECT A.*, NULL AS B
 FROM A
 WHERE NOT EXISTS (SELECT * FROM B WHERE Condition)

一些粗略的伪代码......

注意,A中的所有行都可以通过。只是B的列可以是NULL,如果某个特定行A的连接失败。

docSVsys上的过滤器放入WHERE子句。

答案 1 :(得分:1)

LEFT JOIN 保留左(第一)表中的所有行,无论如何。 ON子句中的条件仅用于匹配右/第二表中哪些行应与左/第一表中的行配对。

如果要从第一个表中排除某些行,请使用WHERE子句:

select top 1000 
   [docSVsys].[sID], [docSVsys].[visibility] 
  ,[Table].[sID],[Table].[enumID],[Table].[valueID] 
from [docSVsys]  with (nolock) 
left Join [DocMVenum1] as [Table] with (nolock) 
  on [Table].[sID] = [docSVsys].[sID]
  and [Table].[enumID] = '140' 
  and [Table].[valueID] in (1,7) 
where [docSVsys].[visibility] in (1)