[英]Oracle SQL: Excluding a record from query results only when TWO conditions are met
[英]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%')
但我不确定,因为你没有解释你想要实现的实际逻辑。 也就是说,如果您混合使用AND
和OR
,请使用括号——至少在您真正理解运算符的优先级之前这样做。
按照它的编写方式,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.