Приоритет логического оператора SQL: и и или
являются ли два утверждения ниже эквивалентными?
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 ответа:
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
для тех, кто любит обращаться к ссылкам (в алфавитном порядке):
Я добавлю 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, вы разделяете последовательные ORs и изменяете приоритет.
- арифметические операторы
- оператор конкатенации
- условия сравнения
- ЭТО [НЕ] NULL, НАПРИМЕР, [НЕ] В
- [НЕ] МЕЖДУ
- Не равно
- не логическое условие
- и логическое условие
- или логическое условие
вы можете использовать круглые скобки для переопределения правил приоритета.
запрос для отображения таблицы истинности булевых выражений с 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