sql - sentencias - precedencia de operadores java
Precedencia del operador lógico SQL: Y y O (4)
- Operadores aritméticos
- Operador de concatenación
- Condiciones de comparación
- IS [NOT] NULL, LIKE, [NOT] IN
- [NO ENTRE
- No igual a
- NO condición lógica
- Y condición lógica
- O condición lógica
Puede usar paréntesis para anular las reglas de precedencia.
¿Son las dos declaraciones a continuación equivalentes?
SELECT [...]
FROM [...]
WHERE some_col in (1,2,3,4,5) AND some_other_expr
y
SELECT [...]
FROM [...]
WHERE some_col in (1,2,3) or some_col in (4,5) AND some_other_expr
¿Hay algún tipo de tabla de verdad que pueda usar para verificar esto?
Agregaré 2 puntos:
- "IN" es efectivamente una serie de OR con paréntesis a su alrededor
- Y tiene precedencia sobre O en todos los idiomas que conozco
Entonces, las 2 expresiones simplemente no son iguales.
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
Entonces, cuando rompe la cláusula IN, divide las operaciones en serie y cambia la prioridad.
Consulta para mostrar una tabla de verdad de expresión booleana de 3 variables:
;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
Resultados para (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
Los resultados para (A=1) OR ( (B=1) AND (C=1) )
son los mismos.
Resultados para ( (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
And
tiene prioridad sobre Or
, entonces, incluso si a <=> a1 Or a2
Where a And b
no es lo mismo que
Where a1 Or a2 And b,
porque eso sería ejecutado como
Where a1 Or (a2 And b)
y lo que quieres, para que sean iguales, es
Where (a1 Or a2) And b
Aquí hay un ejemplo para ilustrar:
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
Para aquellos a los que les gusta consultar referencias (en orden alfabético):