Precedência do operador lógico SQL: e ou

as duas afirmações abaixo são equivalentes?

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

e

SELECT [...]
FROM [...]
WHERE some_col in (1,2,3) or some_col in (4,5) AND some_other_expr
Há alguma tabela da verdade que eu possa usar para verificar isto?

Author: Tanner, 2009-08-07

4 answers

And tem precedência sobre Or, por isso, mesmo que a <=> a1 Or a2

Where a And b 

Não é o mesmo que

Where a1 Or a2 And b,

Porque isso seria executado como

Where a1 Or (a2 And b)

E o que você quer, para torná-los iguais, é

 Where (a1 Or a2) And b
Eis um exemplo 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 aqueles que gostam de consultar referências (por ordem alfabética):

 219
Author: Charles Bretana, 2018-05-08 10:53:23

Vou adicionar 2 pontos:

  • "IN" é efetivamente Serial ORs com parênteses em torno deles
  • e tem precedência sobre ou em todas as línguas que conheço

Assim, as 2 expressões simplesmente não são iguais.

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
Então, quando quebras a cláusula de entrada, divides as notas de série e mudas de precedência.
 29
Author: gbn, 2009-08-07 05:20:55
  1. operadores aritméticos
  2. operador de concatenação
  3. Condições de comparação
  4. É [NÃO] NULO, COMO, [NÃO] EM
  5. [NÃO] ENTRE
  6. não é igual a
  7. não é uma condição lógica
  8. e condição lógica
  9. ou condição lógica

Pode usar parêntesis para anular as regras de precedência.

 16
Author: Yassine Abdul-Rahman, 2014-03-27 22:49:31

Pesquisa para mostrar uma tabela verdade de expressão booleana de 3 variáveis:

;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

Os Resultados para (A=1) OR ( (B=1) AND (C=1) ) são os mesmos.

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
 6
Author: AjV Jsy, 2015-06-18 14:29:33