Пріоритетність логічного оператора SQL: І та Ор


179

Чи є два твердження нижче еквівалентними?

SELECT [...]
FROM [...]
WHERE some_col in (1,2,3,4,5) AND some_other_expr

і

SELECT [...]
FROM [...]
WHERE some_col in (1,2,3) or some_col in (4,5) AND some_other_expr

Чи є якась таблиця істини, яку я міг би використати для перевірки цього?


4
Спробуйте: TT F. (T або T) і F. T або (T і F). Читач коду повинен чітко бачити наміри письменника коду. І письменнику потрібно бути впевненим, що машина робить те, що він задумав. В дужках вирівнюються всі три: читач, автор та машина. :)
Асад Ебрагім

Відповіді:


290

Andмає перевагу над Or, так, навіть якщоa <=> a1 Or a2

Where a And b 

не те саме, що

Where a1 Or a2 And b,

тому що це буде виконано як

Where a1 Or (a2 And b)

і що ви хочете, щоб вони були однаковими, це наступне (використання дужок для зміни правил пріоритету):

 Where (a1 Or a2) And b

Ось приклад для ілюстрації:

Declare @x tinyInt = 1
Declare @y tinyInt = 0
Declare @z tinyInt = 0

Select Case When @x=1 OR @y=1 And @z=1 Then 'T' Else 'F' End -- outputs T
Select Case When (@x=1 OR @y=1) And @z=1 Then 'T' Else 'F' End -- outputs F

Для тих, хто любить звертатися до посилань (в алфавітному порядку):


18
Добре застосовувати дужки, навіть якщо вони не потрібні. дуже мало програмістів (якщо такі є) знають перевагу всіх доступних операторів.
Trismegistos

1
@Trismegistos Хотілося б, щоб це не було так ... не повинно бути так, але я здогадуюсь, що ти маєш рацію.
Чарльз Бретана

1
Це ANDтоді ORпріоритет є частиною стандарту SQL?
Хайме Хаблуцель

@Jaime, Так, і, afaik, це також частина стандарту для всіх мов програмування.
Чарльз Бретана

4
@Bsienn, Не впевнений, що ти зробив, але це не відповідає стандартному SQL та документації на MySQL ... dev.mysql.com/doc/refman/5.0/uk/operator-precedence.html Спробуйте повторити, - уважно це час ... спробуйте declare @x tinyInt = 1 declare @y tinyInt = 0 declare @z tinyInt = 0 select case when @x=1 or @y=1 and @z=1 then'T' else 'F' end select case when (@x=1 or @y=1) and @z=1 then'T' else 'F' end
Чарльз Бретана

33

Я додам 2 бали:

  • "IN" - це фактично послідовні АБО з дужками навколо них
  • І має перевагу над АБО у всіх мовах, які я знаю

Отже, 2 вирази просто не рівні.

WHERE some_col in (1,2,3,4,5) AND some_other_expr
--to the optimiser is this
WHERE
     (
     some_col = 1 OR
     some_col = 2 OR 
     some_col = 3 OR 
     some_col = 4 OR 
     some_col = 5
     )
     AND
     some_other_expr

Отже, розбиваючи пункт IN вгору, ви розділите послідовні АБО вгору та змінили пріоритет.


gbn Чи є асоціативність в ORACLE SQL? ЯКЩО ТАК ТАК, як і де я можу отримати асоціативність усіх операторів?
Асиф Муштак

2
Стільки, як болить мені це сказати, І не має переваги над АБО в рубіні! Щоб зробити речі гірше, && робить мають пріоритет над ||! Одна з причин, що мені не подобається рубін - це порушує принцип найменшого здивування для мене знову і знову. 2.2.1: 007> правда чи правда та хибність => помилка 2.2.1: 008> правда || true && false => true
Alex L

23
  1. Арифметичні оператори
  2. Оператор конкатенації
  3. Умови порівняння
  4. IS [NOT] NULL, LIKE, [NOT] IN
  5. [НЕ] МЕЖ
  6. Не дорівнює
  7. НЕ логічна умова
  8. І логічний стан
  9. АБО логічний стан

Ви можете використовувати круглі дужки для зміни правил пріоритетності.


9

Запит, щоб показати 3-змінну таблицю істинності булевого виразу:

;WITH cteData AS
(SELECT 0 AS A, 0 AS B, 0 AS C
UNION ALL SELECT 0,0,1
UNION ALL SELECT 0,1,0
UNION ALL SELECT 0,1,1
UNION ALL SELECT 1,0,0
UNION ALL SELECT 1,0,1
UNION ALL SELECT 1,1,0
UNION ALL SELECT 1,1,1
)
SELECT cteData.*,
    CASE WHEN

(A=1) OR (B=1) AND (C=1)

    THEN 'True' ELSE 'False' END AS Result
FROM cteData

Результати для (A=1) OR (B=1) AND (C=1):

A   B   C   Result
0   0   0   False
0   0   1   False
0   1   0   False
0   1   1   True
1   0   0   True
1   0   1   True
1   1   0   True
1   1   1   True

Результати для (A=1) OR ( (B=1) AND (C=1) )збігаються.

Результати для ( (A=1) OR (B=1) ) AND (C=1):

A   B   C   Result
0   0   0   False
0   0   1   False
0   1   0   False
0   1   1   True
1   0   0   False
1   0   1   True
1   1   0   False
1   1   1   True
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.