2009-08-06 13 views
113

¿Son equivalentes las dos declaraciones siguientes?Precedencia del operador lógico SQL: Yy O

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 podría utilizar para verificar esto?

+0

Probar: T T F. (T o T) y F. T o (T y F). El lector de código debe ser claramente capaz de ver la intención del escritor del código. Y el escritor debe estar seguro de que la máquina está haciendo lo que pretendía. Los paréntesis alinean los tres: lector, escritor y máquina. :) –

Respuesta

191

And tiene prioridad sobre Or, por lo que, 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 quiero, para hacerlos lo mismo, es

Where (a1 Or a2) And b 

He aquí 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 
+3

Ouch ... gracias ... me alegro de haber hecho esta pregunta :) Aquí hay otra referencia que dice exactamente lo mismo: http://www.praetoriate.com/t_garmany_easysql_sql_logical_operators.htm Tiempo de uso algunos paréntesis –

+10

Es una buena práctica usar paréntesis incluso si no son necesarios. muy pocos programadores (si los hay) conocen la precedencia de todos los operadores disponibles. – Trismegistos

+0

@Trismegistos Ojalá no fuera así ... no debería ser así, pero supongo que tienes razón. –

26

Voy a añadir 2 puntos:

  • "IN" es OR efectivamente en serie con paréntesis alrededor de ellos
  • AND tiene prioridad 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 

Por lo tanto, cuando rompe la cláusula IN, divide el OR de serie y cambia la prioridad.

+0

gbn ¿Hay asociatividad en ORACLE SQL? EN CASO AFIRMATIVO, ¿cómo y dónde puedo obtener la asociatividad de todos los operadores? – UnKnown

+1

¡Por mucho que me duela decirlo, Y no tiene precedencia sobre O en Ruby! Para empeorar las cosas, && * does * tiene prioridad sobre ||! Una de las razones por las que no me gusta el rubí: viola el principio del menor asombro una y otra vez. 2.2.1: 007> verdadero o verdadero y falso => falso 2.2.1: 008> true || true && false => true –

14
  1. operadores aritméticos
  2. operador de concatenación
  3. Condiciones de comparación
  4. [no] es NULL, como, [NO] EN
  5. [NO] ENTRE
  6. No igual a
  7. NO Condición lógica
  8. Y condición lógica
  9. O condición lógica

Puede usar paréntesis para anular las reglas de precedencia.

5

de consulta para mostrar un valor booleano tabla de verdad expresión 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 

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 
Cuestiones relacionadas