Some random IN vs. NOT IN with T-SQL
I'll try to expand on this, but anyway, here's some examples about how you have to be careful with IN and NOT IN in T-SQL in terms of when results will be returned. If the list you're comparing to has nulls, watch out. If the item you're comparing has nulls, watch out. If the list could be empty, check for that. IN and NOT IN may behave differently than you expect in all these situations. Below are most of the iterations.
--in
select 'row' where 1 in (1,2,3)--returns
select 'row' where 1 in (select 1 union select 2)--returns
select 'row' where 1 in (select null union select 2)
--does NOT return - cannot determine if 1 "in" null, maybe it is, who knows?
select 'row' where 1 in (select top 0 f1 from (select 1 f1 union select 2) qry)
--NO return b/c the top 0 qry returns "nothing", and 1 is NOT "in" nothing ("in nothing" = false)
--so if the scenario is that you want to return "all" if the list is empty, then you have to add a check like this:
select 'row'
where
--include all if the list is empty
not exists (select top 0 f1 from (select 1 f1 union select 2) qry)
or
--if the list is not empty, return matches only
1 in (select top 0 f1 from (select 1 f1 union select 2) qry)
--NOW returns because the list is empty (top 0)
--not in
select 'row' where 1 not in (1,2,3) --no return
select 'row' where 1 not in (select 1 union select 2) --no return
select 'row' where 1 not in (select 2 union select 3)--returns
select 'row' where 1 not in (select null union select 2)
--does NOT return - cannot determine if 1 "not in" null, maybe it is, who knows?
select 'row' where 1 not in (select top 0 f1 from (select 1 f1 union select 2) qry)
--Returns b/c the top 0 qry returns "nothing", and 1 is "not in" nothing ("not in nothing" = true)
--so if the scenario is that you want to return "all" if the list is empty, same "not exists / or" check as above:
select 'row'
where
--include all if the list is empty
not exists (select top 5 f1 from (select 1 f1 union select 2) qry)
or
--if the list is not empty, return matches only
1 NOT in (select top 5 f1 from (select 1 f1 union select 2) qry)
--NO return b/c 1 "not in" the exclusion list = true
There you go, happy coding.
Comments
Post a Comment