这是我的代码
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#不同
答案 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