SQL Server LEFT JOIN和WHERE子句

时间:2013-10-28 13:45:10

标签: sql sql-server left-join

这是我的代码

SELECT ID, Name, Phone 
FROM Table1 
LEFT JOIN Table2 ON Table1.ID = Table2.ID
WHERE Table1.ID = 12 AND Table2.IsDefault = 1

Table2为null时会出现问题,因此查询不返回任何内容。

如何保留查询的最后一部分AND Table2.IsDefault = 1可选?

我尝试使用OR来短路查询,但我发现它的工作方式与C#不同

5 个答案:

答案 0 :(得分:29)

SELECT ID, Name, Phone 
FROM Table1 
LEFT JOIN Table2 
ON Table1.ID = Table2.ID AND Table2.IsDefault = 1
WHERE Table1.ID = 12

答案 1 :(得分:2)

 AND COALESCE(Table2.IsDefault,1) = 1

阅读评论,看起来您的最佳解决方案实际上是将条件移至联接:

SELECT ID, Name, Phone 
FROM Table1 
LEFT JOIN Table2 ON Table1.ID = Table2.ID AND Table2.IsDefault = 1
WHERE Table1.ID = 12 

因为它是一个OUTER连接,如果匹配失败,你仍然会保留任何Table1信息,并且给出“Table2将始终返回1个条目”的语句,你不会冒着通过移动条件来过滤其他连接结果的风险。您将获得与在WHERE子句中放置条件的相同结果。

将conidtion移动到ON子句的原因是COALESCE()ISNULL()OR都会导致索引出现问题。根据ON子句中的条件,我们不需要任何这些条件,因此最终应该有更好的执行计划。

答案 2 :(得分:1)

试试这个:

SELECT ID, Name, Phone 
FROM Table1 
LEFT JOIN Table2 ON Table1.ID = Table2.ID
WHERE Table1.ID = 12 AND isnull(Table2.IsDefault,1) = 1

你几乎在那里: - )

答案 3 :(得分:1)

SELECT ID, Name, Phone FROM Table1 
  LEFT JOIN Table2 ON Table1.ID = Table2.ID
  WHERE Table1.ID = 12 
    AND (Table2.IsDefault IS NULL OR Table2.IsDefault = 1);

答案 4 :(得分:0)

使用子查询在表2的结果加入之前过滤表2的结果:

SELECT ID, Name, Phone 
FROM Table1 
LEFT JOIN (SELECT * FROM Table2 WHERE IsDefault = 1) AS Table2 ON Table1.ID = Table2.ID
WHERE Table1.ID = 12