17

当我执行以下查询时,即使有 11 条记录匹配,也没有按写入返回。但是,如果我删除第 6 行和第 9 行的括号,所有 11 条记录都会按预期返回。

1  select obj_id, obj_title, UI_DISPLAYNAME
2  from PITS_OBJECT 
3  LEFT OUTER JOIN ui_displayname_view ON obj_create_ui_id = UI_ID  
4  where
5  /* w/ parens, no results, w/o parens, expected results */
6  (
7     Upper( UI_DISPLAYNAME ) LIKE Upper( '%smith%' )  
8     OR Upper( OBJ_TITLE ) LIKE Upper( '%smith%' ) 
9  )
10 /* end w/ parents, no results.... */
11 AND OBJ_ID IN (select obj_id from PITS_OBJECT where 
12     (UPPER( OBJ_TITLE ) LIKE UPPER( '%smith%' )) 
13     AND obj_id in( select sa_obj_id as obj_id from security_access 
14         where sa_type_id = 494 
15         and sa_usrgrp_id = 35
16         and sa_usrgrp_type_id = 230 
17         union 
18         select sa_obj_id from security_access 
19         where sa_type_id = 494 
20         and sa_usrgrp_type_id = 231 
21         and sa_usrgrp_id in ( select ug_gi_id from user_group where ug_ui_id = 35)) )

为什么这很重要?OR 语句是否意味着其中一个或另一个必须为真?我在这里想念什么?

4

5 回答 5

19

三个字:操作顺序。就像您在数学中学到的一样,某些运算符优先于其他运算符(例如乘法先于加法),除非您使用括号来强制执行。在这种情况下,AND的优先级高于OR

在不添加您自己的括号的情况下,您的WHERE子句将按如下方式进行评估:

Upper( UI_DISPLAYNAME ) LIKE Upper( '%smith%' )
OR 
(Upper( OBJ_TITLE ) LIKE Upper( '%smith%' ) 
    AND OBJ_ID IN (select obj_id from PITS_OBJECT where 
    ...)

但是,当您手动添加这些括号时,您会强制OR首先评估 。

(Upper( UI_DISPLAYNAME ) LIKE Upper( '%smith%' )
    OR Upper( OBJ_TITLE ) LIKE Upper( '%smith%' ))
AND OBJ_ID IN (select obj_id from PITS_OBJECT where 
...

编辑:我应该直接回答你关于为什么要取回更多数据的问题。原因是,如果没有括号,引擎会在发现第 7 行为真时将其检查短路。换句话说,它将包括所有记录 where Upper( UI_DISPLAYNAME ) LIKE Upper( '%smith%' ),而不管其他条件如何。

当您添加这些括号时,逻辑会发生变化。它将包括记录 where Upper( UI_DISPLAYNAME ) LIKE Upper( '%smith%' ) OR Upper( OBJ_TITLE ) LIKE Upper( '%smith%' ),然后它检查记录 ALSO 是否满足从第 12 行开始的内部选择。那些额外的记录不会显示,因为它们不符合该内部选择的标准。

于 2011-11-17T18:44:56.110 回答
16

您的 where 子句目前类似于以下内容:

(A || B) && C && D

不加括号如下

A || B && C && D

这相当于

A || (B && (C && D))
于 2011-11-17T18:47:14.090 回答
2

它与ANDOR运算符的优先级有关。AND具有更高的优先级。 http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/conditions001.htm#i1034834

于 2011-11-17T18:44:07.377 回答
0

因为您已将 where 语句更改为始终返回 where Upper( OBJ_TITLE ) LIKE Upper( '%smith%' )为 true 的记录,而不管您的下一个 AND

于 2011-11-17T18:42:47.530 回答
0

这是基本的操作顺序。括号表示在测试其他任何内容之前测试所有内容。评估括号中的项目后返回的值将用于评估其余部分。由于 AND 优先于 OR,括号使 SQL 首先评估 OR。

于 2011-11-17T18:45:11.727 回答