web-dev-qa-db-ja.com

SQLクエリに括弧を追加すると、結果が変わるのはなぜですか?

次のクエリを実行すると、一致するレコードが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ステートメントは、どちらかが真でなければならないことを意味しませんか?ここで何が欠けていますか?

15
Sam F.

3つの単語:操作の順序。数学で学んだように、括弧を使用して強制しない限り、特定の演算子が他の演算子よりも優先されます(乗算は加算の前に行われます)。この場合、ANDORよりも優先されます。

独自の括弧を追加しないと、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行目が真であることが検出された場合にエンジンがチェックを短絡するためです。つまり、他の基準に関係なく、Upper( UI_DISPLAYNAME ) LIKE Upper( '%smith%' )であるすべてのレコードが含まれます。

これらの括弧を追加すると、ロジックが変更されます。 Upper( UI_DISPLAYNAME ) LIKE Upper( '%smith%' ) OR Upper( OBJ_TITLE ) LIKE Upper( '%smith%' )のレコードが含まれ、レコードが12行目から始まる内部選択も満たしていることを確認します。これらの追加レコードは、その内部の基準を満たしていないため、表示されません。選択する。

14
ean5533

現在、where句は次のようになっています。

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

括弧なしの場合は以下のようになります

A || B && C && D

これは

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

これは、ANDおよびOR演算子の優先順位と関係があります。 ANDの優先順位が高くなります。 http://download.Oracle.com/docs/cd/B19306_01/server.102/b14200/conditions001.htm#i1034834

1
Raihan

Whereステートメントを変更して、次のANDに関係なく、Upper( OBJ_TITLE ) LIKE Upper( '%smith%' )がtrueであるレコードを常に返すようにしたためです。

0
Maess

これが基本的な操作の順序です。括弧は、他のものがテストされる前にすべてがテストされることを意味します。括弧内の項目を評価した後に返された値は、残りを評価するために使用されます。 ANDはORよりも優先されるため、括弧はSQLにORを最初に評価させます。

0
Jemaclus