我前几天正在调试存储过程,并发现了类似这样的逻辑:
SELECT something
FROM someTable
WHERE idcode <> (SELECT ids FROM tmpIdTable)
这没有任何回报。我认为“&lt;&gt;”看起来有点奇怪所以我把它改成了“NOT IN”然后一切正常。我想知道为什么会这样?这是一个非常古老的过程,我不确定该问题存在多久,但我们最近从SQL Server 2005切换到SQL Server 2008时发现了这个问题。 “&lt;&gt;”之间的真正区别是什么?和“NOT IN”并且Server2005和2008之间的行为发生了变化?
答案 0 :(得分:20)
SELECT something
FROM someTable
WHERE idcode NOT IN (SELECT ids FROM tmpIdTable)
检查列表中的任何值。
但是,NOT IN不是NULL容错的。如果子查询返回一组包含NULL的值,则根本不会返回任何记录。 (这是因为NOT IN内部优化为idcode <> 'foo' AND idcode <> 'bar' AND idcode <> NULL
等,这将永远失败,因为任何与NULL的比较都会产生UNKNOWN,从而阻止整个表达式变为TRUE。)
一个更好的,容忍NULL的变体就是:
SELECT something
FROM someTable
WHERE NOT EXISTS (SELECT ids FROM tmpIdTable WHERE ids = someTable.idcode)
SELECT something
FROM someTable
WHERE idcode <> (SELECT ids FROM tmpIdTable)
只会检查第一个值。事实证明,这种假设至少对SQL Server来说是错误的,它实际上会触发他的错误:
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.
答案 1 :(得分:13)
试试这个,因为索引使用可能会运行得更快:
SELECT something
FROM someTable
LEFT OUTER JOIN tmpIdTable ON idcode=ids
WHERE ids IS NULL
答案 2 :(得分:8)
<>
是一个“单数”NOT
操作; NOT IN
是一个集合操作,因此前者不起作用是有道理的。但是,我不知道它是否可以在以前版本的SQL Server下完成。
答案 3 :(得分:5)
当且仅当tmpIdTable没有返回任何行或单行时,此代码才有效:
SELECT something
FROM someTable
WHERE idcode <> (SELECT ids FROM tmpIdTable)
如果返回多行,您将收到如下错误:
Msg 512,Level 16,State 1,Line 1 子查询返回的值超过1。当子查询遵循=,!=,&lt;,&lt; =,&gt;,&gt; =或子查询用作表达式时,不允许这样做。
这与嵌套标量产生的错误相同,意外地产生多行,如:
SELECT *,(从t1 WHERE等中选择等等)FROM t2
十年内在SQL Server中没有任何改变WRT这一点,所以我希望原始代码中关于嵌套查询的假设已被打破。
如果没有返回任何行,则结果将为空,因为<> NULL
永远不为真(假设为ANSI NULL)。
此代码适用于任意数量的行:
SELECT something
FROM someTable
WHERE idcode NOT IN (SELECT ids FROM tmpIdTable)
但是,仍然存在NULL问题。
答案 4 :(得分:3)
我不知道为什么你会写WHERE idcode <> (SELECT ids FROM tmpIdTable)
之类的东西。 SELECT语句将返回一组元组,并且您的idcode将会或不会在此集合中。 “WHERE idcode NOT IN (SELECT ids FROM tmpIdTable)
”就是这样做的方式。
答案 5 :(得分:3)
如果SELECT子查询返回零行,则为NULL。将NULL与任何内容进行比较时,结果始终为UNKNOWN,并且永远不为TRUE。令人困惑的是,NOT UNKNOWN等于UNKNOWN。
尽可能避免使用三值逻辑(TRUE,FALSE,UNKNOWN)。一旦掌握了它,就不难避免。
如果SELECT子查询只返回一个值,则不等式的比较应返回您期望的结果。
如果SELECT子查询返回多个值,则应该出错。
通常,NOT IN将返回您在测试集合中的非成员资格时所期望的结果。
这种回应与其他回复重叠,但措辞略有不同。
编辑以添加有关NOT IN的更多详细信息:
我在Oracle中搜索了一些NOT IN,并且我在半小时前学到了一些我不知道的东西。 NOT IN是NULL敏感的。特别是,
X NOT IN (SELECT ...)
与
不一样NOT (X IN SELECT ...))
我可能需要修改我之前的回复!
答案 6 :(得分:2)
使用NOT IN的查询可能很脆弱:
答案 7 :(得分:-1)
在某些版本的SQL != 中应该用于“not equals”逻辑语句。 你试过了吗?
答案 8 :(得分:-1)
<>
本质上是“不”
在SQL WHERE NOT demo上,我尝试了以下操作
失败:
WHERE NOT Country='Mexico' AND WHERE NOT country ='Sweden'
作品
WHERE NOT Country='Mexico' AND country<>'Sweden'