Reputation: 1
I am using SQL Server 2008, and when I perform a left join to a table where the outer table does not have any records then I am seeing weird behavior from my where clause. If I do a check for a value from my outer table being 'not null' it sometimes returns 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)
When my f.status = 0
and b.Price
does not exist (or, appears as null in the select) this query selects records where f.status = 0
and b.Price is null
, even though (FALSE OR FALSE) should be FALSE.
If I just perform this query, it works as expected and anything without a record in 'bar' does not get selected.
select *
from foo f left join bar b on b.id=f.id
where f.id=@id and b.Price is not null
Having b.Price is not null
as part of an or
operation seems to be causing issue for some reason. What could be wrong with this query? I run the same query with similar data on a SQL Server 2012 machine and do not see this issue, could it be related the the version of SQL Server I am using?
Upvotes: 0
Views: 3744
Reputation: 683
Would a CASE statement work?
IE
SELECT
(etc etc code)
CASE WHEN b.Price is not null THEN 1 ELSE 0 END AS [MyBooleanCheck]
FROM (etc etc code)
Upvotes: 1
Reputation: 696
You could try an OUTER APPLY
like this:
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
And I also suggest using the columns instead of *, bad practice. The Outer Apply is sort of like a left join and in this case it will filter all the data from the bar table and bring you back only the data you need.
Upvotes: 1
Reputation: 1269873
These two formulations are not the same, as you have discovered.
In the first query, price
can be NULL
for two reasons:
left join
.b.Price
is nullI highly recommend the second approach, putting the condition in the on
clause. However, if you do use the first one, make the comparison to a column used in the join
:
where f.id = @id and (f.status = 1 or b.id is not null)
Upvotes: 1