我正在使用SQL Server 2008,当我对外表没有任何记录的表执行左连接时,我看到来自where子句的奇怪行为。如果我检查外部表格中的值是否为“空”'它有时返回true。
select *
from foo f left join bar b on b.id=f.id
where f.id=@id and (f.status = 1 or b.Price is not null)
当我的f.status = 0
和b.Price
不存在(或在选择中显示为空)时,此查询会选择f.status = 0
和b.Price is null
的记录,即使({FALSE}或者错误)应该是假的。
如果我只是执行此查询,它会按预期工作,并且在' bar'中没有记录的任何内容没有被选中。
select *
from foo f left join bar b on b.id=f.id
where f.id=@id and b.Price is not null
将b.Price is not null
作为or
操作的一部分似乎由于某种原因导致问题。这个查询有什么问题?我在SQL Server 2012计算机上使用类似数据运行相同的查询,但没有看到此问题,是否与我正在使用的SQL Server版本相关?
答案 0 :(得分:1)
正如您所发现的,这两种配方不相同。
在第一个查询中,price
可以是NULL
,原因有两个:
left join
没有匹配。b.Price
为空我强烈推荐第二种方法,将条件放在on
子句中。但是,如果您使用第一个,请与join
中使用的列进行比较:
where f.id = @id and (f.status = 1 or b.id is not null)
答案 1 :(得分:1)
您可以尝试这样的OUTER APPLY
:
SELECT *
FROM foo f
OUTER APPLY (
SELECT *
FROM bar b
WHERE f.id = b.id
AND (
f.STATUS = 1
OR b.Price IS NOT NULL
) b
)
WHERE f.id = @id
我还建议使用列而不是*,不好的做法。外部应用有点像左连接,在这种情况下,它将过滤条形表中的所有数据,并仅返回所需的数据。
答案 2 :(得分:0)
CASE 语句是否有效?
浏览器
选择
(等代码)
CASE WHEN b.Price is not null THEN 1 ELSE 0 END AS [MyBooleanCheck]
FROM(等代码)