繁体   English   中英

Oracle 查询:只有一条记录时WHERE NOT LIKE不排除记录

[英]Oracle query: WHERE NOT LIKE is not excluding record when only one record exists

我有以下查询

select cand_id 
from cand_kw
WHERE client_id='mamasandpapas' AND UPPER(kw) LIKE '%MARAH%' OR UPPER(kw) LIKE '%ANDREW%' AND UPPER(kw) NOT LIKE '%KOCH%' 

在数据库中有以下记录:

Andrew Postings
Andrew Postings
Andrew McDee
Marah Koch

所以有 Andrew 和 Andrew 的三行,但只有一个记录有 Marah。

如果我将查询更改为以下内容,则正确排除了两个 Andrew Postings

select cand_id
from cand_kw
 WHERE client_id='mamasandpapas' AND UPPER(kw) LIKE '%MARAH%' OR UPPER(kw) LIKE '%ANDREW%' AND UPPER(kw) NOT LIKE '%POSTINGS%' 

所以看起来如果只有一个记录存在,那么结果会被返回,即使它们应该被排除在外。

这是使用一个非常旧的版本 Oracle (9i),它的搜索字段 (kw) 代表关键字,是一个包含一堆关键字的 CLOB。

这是一个非常古老的系统,不是我设计的。

在第一种情况下,谁能解释为什么 Marah Koch 没有被排除在外,而 Andrew Postings 的记录却被排除在外?

据推测,您想要这样的where子句:

WHERE client_id = 'mamasandpapas' AND
      (UPPER(kw) LIKE '%MARAH%' OR UPPER(kw) LIKE '%ANDREW%' AND UPPER(kw) NOT LIKE '%KOCH%')

但我不确定,因为你没有解释你想要实现的实际逻辑。 也就是说,如果您混合使用ANDOR ,请使用括号——至少在您真正理解运算符的优先级之前这样做。

按照它的编写方式,NOT LIKE "%KOCH%" 只会在 LIKE "%ANDREW%" 计算结果为 True 时计算。 这是关于 Marah Koch 的记录的原始 WHERE 子句的流程。

首先SQL看client_id是不是'mamasandpapas'。 很好,接下来,它看到一个 AND,这意味着幸运的是,它后面的任何内容也必须为真,WHERE 子句才为真。 Upper(kw) 确实像“%MARAH%”。 然后它接下来看到 OR,SQL 决定它可以忽略 rest,因为如果 OR 任一侧的任何表达式的计算结果为真,那么它就完成了计算,因为 Upper(kw) LIKE '%MARAH%' 已经计算为真。 所以它甚至没有达到 Upper(kw) NOT LIKE '%KOCH%'。

同样,在你的第二个 WHERE 子句示例中,它似乎只起作用,因为在 Andrew Postings 的情况下,在 client_id 评估为真之后,AND 说看看 Upper(kw) 是否像'%MARAH%',哦它不是,好吧,现在我们转到 OR 的另一边,Upper(kw) is LIKE '%ANDREW%' 但是等等,现在我看到一个 AND,这意味着 Upper(kw) LIKE'%ANDREW%' AND 上的任何内容另一边必须为真,WHERE 才为真。 如果您将一条记录添加到您的 Marah Postings 表中,它仍将在第二个示例中返回。

我为此学到的术语是“裸手术室”。 换句话说,最好用括号“装饰”任何 OR 语句,以提高可读性,因为这是大多数人理解 AND 和 OR 逻辑的方式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM