Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"<>" vs "NOT IN"

Tags:

I was debugging a stored procedure the other day and found some logic something like this:

SELECT something FROM someTable WHERE idcode <> (SELECT ids FROM tmpIdTable) 

This returned nothing. I thought it looked a little odd with the "<>" so I changed it to "NOT IN" and then everything worked fine. I was wondering why this is? This is a pretty old proc and I am not really sure how long the issue has been around, but we recently switched from SQL Server 2005 to SQL Server 2008 when this was discovered. What is the real difference between "<>" and "NOT IN" and has the behavior changed between Server2005 and 2008?

like image 605
DJ. Avatar asked May 13 '09 14:05

DJ.


2 Answers

SELECT something FROM someTable WHERE idcode NOT IN (SELECT ids FROM tmpIdTable) 

checks against any value in the list.

However, the NOT IN is not NULL-tolerant. If the sub-query returned a set of values that contained NULL, no records would be returned at all. (This is because internally the NOT IN is optimized to idcode <> 'foo' AND idcode <> 'bar' AND idcode <> NULL etc., which will always fail because any comparison to NULL yields UNKNOWN, preventing the whole expression from ever becoming TRUE.)

A nicer, NULL-tolerant variant would be this:

SELECT something FROM someTable WHERE NOT EXISTS (SELECT ids FROM tmpIdTable WHERE ids = someTable.idcode) 

EDIT: I initially assumed that this:

SELECT something FROM someTable WHERE idcode <> (SELECT ids FROM tmpIdTable) 

would check against the first value only. It turns out that this assumption is wrong at least for SQL Server, where it actually triggers his error:

Msg 512, Level 16, State 1, Line 1 Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression. 
like image 115
Tomalak Avatar answered Nov 17 '22 04:11

Tomalak


try this, may run faster because of index usage:

SELECT something FROM someTable     LEFT OUTER JOIN tmpIdTable ON idcode=ids WHERE ids IS NULL 
like image 43
KM. Avatar answered Nov 17 '22 04:11

KM.