用于字符串比较的Oracle NOT BETWEEN与< =和> =的结果不同

时间:2014-12-05 19:00:42

标签: oracle comparison-operators

使用Oracle 11gR2 Expression Edition。 我的数据如下所示

ordertype
---------
ZOCO
ZOSA
ZOST

我们正在尝试找出列不在某个值范围之间的记录。

如果我使用&lt; =和&gt; =运算符运行查询: SELECT * FROM table where ordertype <= 'ZAAA' OR ordertype >= 'ZZZZ';  然后我得到0结果。 这是正确的答案。

但是,如果我使用NOT BETWEEN: SELECT * FROM table where ordertype NOT BETWEEN 'ZAAA' AND 'ZZZZ'; ,然后它会给出多次点击。

我的理解是两种语法都应该给出相同的结果,但事实并非如此。我错过了什么?原因我想使用NOT BETWEEN,因为我们现有的许多代码已经有了这种语法,我不想在不理解原因的情况下改变它。

谢谢。


感谢所有发帖的人。我再次运行查询并修复了&#34; OR&#34;在第一个查询中,结果是一样的。我仍然有一个问题,为什么Oracle字符排序没有按预期识别它,但我的问题是关于NOT BETWEEN和&lt;&gt;之间的区别。是一种误报。我为混乱道歉。

4 个答案:

答案 0 :(得分:10)

SELECT * FROM table where ordertype <= 'ZAAA' AND ordertype >= 'ZZZZ';

没有字符串可以&lt; ='ZAAA'&gt; ='ZZZZ'。 你需要改为使用析取:

SELECT * FROM table where ordertype < 'ZAAA' OR ordertype > 'ZZZZ';

BTW,鉴于BETWEEN具有包容性,NOT BETWEEN是独占的


这是一个常见的陷阱。你必须记住De Morgan's Laws

  

not (A and B) (not A) or (not B)

相同

您可以尝试使用这个简单的实例来说服自己,这些结果非常一致:http://sqlfiddle.com/#!4/d41d8/38326


话虽如此,{em> not 之类的ZOCO字符串在ZAAAZZZZ之间的唯一方式(我可以看到)将是:< / p>

  • Z(即:'Z'||CHR(0)||'OCO'
  • 后面隐藏着一些隐藏的角色
  • 使用区域设置,例如Z - 某些内容实际上被视为不同的字母,其排序顺序超出了给定范围。我不知道这样的语言环境是否存在,但是例如,在Welch中,LL被视为应该在普通L之后排序的单个字母。请参阅http://en.wikipedia.org/wiki/Alphabetical_order#Language-specific_conventions
  • 在您的数据中使用0,例如ОO而不是{{1}}。

答案 1 :(得分:2)

您对两种陈述相同的理解是不正确的。 NOT BETWEEN未按照您的思维方式进行评估。它只返回参数的BETWEEN评估之外的结果。

如果你检查 BETWEEN 的Oracle文档,它会说 -

The value of

expr1 NOT BETWEEN expr2 AND expr3
is the value of the expression

NOT (expr1 BETWEEN expr2 AND expr3)

答案 2 :(得分:2)

如果不在值之间,则必须是&lt; OR&gt;,而不是AND。

答案 3 :(得分:2)

在第一个查询中,您要求的记录同时小于'ZAAA' 大于'ZZZZ'。当然,没有满足这两个要求的这样的值,因此返回零记录。

在第二个查询中,您要求记录的 小于'ZAAA' 大于'ZZZZ'(即不在这些记录之间)边界[not between...])。存在这样的记录的可能性,并且正如您的select语句所证明的那样,确实存在由语句返回的记录。