Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql “”vs“不在”_Sql_Sql Server_Sql Server 2005_Sql Server 2008 - Fatal编程技术网

Sql “”vs“不在”

Sql “”vs“不在”,sql,sql-server,sql-server-2005,sql-server-2008,Sql,Sql Server,Sql Server 2005,Sql Server 2008,前几天我在调试一个存储过程,发现了一些类似这样的逻辑: SELECT something FROM someTable WHERE idcode <> (SELECT ids FROM tmpIdTable) 结果一无所获。我觉得它看起来有点奇怪,所以我把它改成不在,然后一切都很好。我想知道为什么会这样?这是一个非常旧的过程,我不确定这个问题已经存在多久了,但当发现这个问题时,我们最近从SQLServer2005切换到了SQLServer2008。与否的真正区别是什么?Server

前几天我在调试一个存储过程,发现了一些类似这样的逻辑:

SELECT something
FROM someTable
WHERE idcode <> (SELECT ids FROM tmpIdTable)
结果一无所获。我觉得它看起来有点奇怪,所以我把它改成不在,然后一切都很好。我想知道为什么会这样?这是一个非常旧的过程,我不确定这个问题已经存在多久了,但当发现这个问题时,我们最近从SQLServer2005切换到了SQLServer2008。与否的真正区别是什么?Server2005和2008之间的行为是否发生了变化?

是一个单数NOT操作;NOT IN是一个集合操作,所以前者不起作用是有道理的。但是,我不知道它是否在以前版本的SQL Server下这样做

SELECT something
FROM someTable
WHERE idcode NOT IN (SELECT ids FROM tmpIdTable)
检查列表中的任何值

但是,NOT IN不允许为空。如果子查询返回一组包含NULL的值,则不会返回任何记录。这是因为在内部,NOT IN被优化为idcode“foo”和idcode“bar”以及idcode NULL等,这将始终失败,因为与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.
尝试此操作,可能会因为索引使用而运行得更快:

SELECT something
FROM someTable
    LEFT OUTER JOIN tmpIdTable ON idcode=ids
WHERE ids IS NULL

我不知道您为什么要编写类似于whereidcode从tmpIdTable中选择id这样的代码。SELECT语句将返回一组元组,您的idcode将或不在该元组中。其中idcode不在从tmpIdTable选择ID中是执行此操作的方法。

在某些SQL版本中!=应用于not equals逻辑语句。
您试过了吗?

当且仅当tmpIdTable中没有行或只返回一行时,此代码才有效:

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

但是,NULL仍然可能存在问题。

如果SELECT子查询返回零行,则为NULL。如果将NULL与任何对象进行比较,结果总是未知的,并且永远不会为真。令人困惑的是,“不未知”等于“未知”

我尽可能避免三值逻辑真、假、未知。一旦你掌握了窍门,就不难避免了


如果SELECT子查询只返回一个值,则不等式比较应返回您期望的结果


如果SELECT子查询返回多个值,则会出现错误

通常,当您测试集合中的非成员身份时,NOT In将返回您期望的结果

这个回答与其他回答重叠,但措辞有点不同

编辑以添加有关不在的更多详细信息:

我做了一些关于不在甲骨文的搜索,我学到了一些半小时前我不知道的东西。NOT IN是空敏感的。特别是,

X NOT IN (SELECT ...)
不一样

NOT (X IN SELECT ...))

我可能不得不修改我先前的回答

使用NOT IN的查询可能很脆弱:

本质上也不是

我试了以下方法

失败:

WHERE NOT Country='Mexico' AND WHERE NOT country ='Sweden'
工作


这就是我知道如何修复它的原因,我只是不知道它背后的逻辑到底是什么。如果子查询以某种方式排序,例如列表中最大的[事物],则该语句可能有意义。你是对的,如果子查询是按顺序排序的,符号可能会有一些意义,但我无论如何都会避免它,因为它容易出错——很容易忽略它的意图。无论是谁在以后删除或更改子查询的顺序,都可能会被查询为什么不返回任何结果所困扰。True。为了消除歧义,我总是在子查询中输入TOP 1或MAX/GROUP BY或类似值。仅仅针对一组值使用,对我的共享来说,副作用太大了。。。我想犯错是人的本性我真的认为选择。。。是有效的,但当子查询返回多个值时,至少SQL Server不接受它。无论如何,这不是一个好的做法。和“!=”在SQL Server上是等效的。没有坚持使用“!=”的版本。但是,这是ANSI SQL的标准方法吗,尽管我个人倾向于使用!=通常情况下,我没有见过这样的情况:它没有为联接或子查询生成相同的QEP,因此性能也相同。实际上,我今天上午与一位同事进行了同样的对话。这是相似的,但不是完全正确的答案。至少在概念上,如果subselect返回零或一行,它甚至是错误的。因为您要问的是标量idcode是否等于零元素或一元素列表。标量实际上永远不会等于列表,即使它等于一个元素列表中的唯一元素。事实上,我从不使用该构造,我通常会将其视为代码气味。其中idcode不在。。。等同于idcode ALL…这并不是在回答问题。这是在询问和之间的差异
在子查询中使用时不在中。“不”和“不在”不是一回事。此外,您不能像第一个WHERE子句中那样使用WHERE两次。问题是关于NOT in,答案是关于NOT。
WHERE NOT Country='Mexico' AND WHERE NOT country ='Sweden'
WHERE NOT Country='Mexico' AND country<>'Sweden'