18

这是我的代码

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

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

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

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

4

5 回答 5

33
SELECT ID, Name, Phone 
FROM Table1 
LEFT JOIN Table2 
ON Table1.ID = Table2.ID AND Table2.IsDefault = 1
WHERE Table1.ID = 12
于 2013-10-28T13:52:11.520 回答
3
 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 子句中 相同的结果。

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

于 2013-10-28T13:47:37.493 回答
2

试试这个 :

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

你快到了:-)

于 2013-10-28T13:47:41.823 回答
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);
于 2013-10-28T13:48:16.620 回答
1

在与表 1 连接之前,使用子查询过滤表 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
于 2013-10-28T13:48:54.843 回答