T-SQL “not in (select ” not working (as expected)

China☆狼群 提交于 2020-01-06 05:40:15

问题


I have an ordinary one-to-many relation:

customer.id = order.customerid

I want to find customers who have no associated orders.

I tried:

-- one record
select * from customers where id = 123

-- no records
select * from orders where customerid = 123

-- NO RECORDS
select * 
from customers 
where id not in (select customerid from orders)

-- many records, as expected.
select * 
from customers 
where not exist (select customerid from orders 
                 where customers.customerid = customer.id)

Am I mistaken, or should it work?


回答1:


NOT IN does not behave as expected when the in-list contains NULL values.

In fact, if any values are NULL, then no rows are returned at all. Remember: In SQL, NULL means "indeterminate" value, not "missing value". So, if the list contains any NULL value then it might be equal to a comparison value.

So, customerid must be NULL in the orders table.

For this reason, I strongly recommend that you always use NOT EXISTS with a subquery rather than NOT IN.




回答2:


I normally do this via a left join that looks for nulls created when the join fails:

SELECT c.* 
FROM
  customers c
  LEFT JOIN orders o
  ON c.id = o.customerid
WHERE
  o.customerid IS NULL

Left join treats the customer table as "solid" and connects orders to it where there is an order with a given customer id and puts nulls where there isn't any matching order, hence the orders side of the relationship has "holes" in the data. By then saying we only want to see the holes (via the where clause), we get a list of "customers with no orders"

As per the comments I've always worked to the rule "do not use IN for lists longer than you'd be prepared to write by hand" but increasingly optimisers are rewriting IN, EXISTS and LEFT JOIN WHERE NULL queries to function identically as they're all recognised patterns of "data in A that has no matching data in B"



来源:https://stackoverflow.com/questions/57085105/t-sql-not-in-select-not-working-as-expected

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!