web-dev-qa-db-fra.com

Ordre de priorité de l'opérateur logique SQL: And and Or

Les deux déclarations ci-dessous sont-elles équivalentes?

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

et

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

Y a-t-il une sorte de table de vérité que je pourrais utiliser pour vérifier cela?

156
nc.

And a priorité sur Or, donc, même si a <=> a1 Or a2

Where a And b 

n'est pas la même chose que

Where a1 Or a2 And b,

parce que cela serait exécuté comme

Where a1 Or (a2 And b)

et ce que vous voulez, pour les rendre identiques, est le suivant (en utilisant des parenthèses pour remplacer les règles de priorité):

 Where (a1 Or a2) And b

Voici un exemple pour illustrer:

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

Pour ceux qui aiment consulter des références (par ordre alphabétique):

258
Charles Bretana

Je vais ajouter 2 points:

  • "IN" est effectivement une série d'opérateurs avec des parenthèses autour d'eux
  • AND a la priorité sur OR dans toutes les langues que je connais

Donc, les 2 expressions ne sont tout simplement pas égales.

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

Ainsi, lorsque vous séparez la clause IN, vous divisez les OR en série et vous modifiez la priorité.

32
gbn
  1. Opérateurs arithmétiques
  2. Opérateur de concaténation
  3. Conditions de comparaison
  4. IS [NOT] NULL, COMME, [NOT] IN
  5. [PAS ENTRE
  6. Pas égal à
  7. PAS de condition logique
  8. ET condition logique
  9. OU condition logique

Vous pouvez utiliser des parenthèses pour remplacer les règles de priorité.

21

Requête pour afficher une table de vérité d'expression booléenne à 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

Résultats pour (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

Résultats pour (A=1) OR ( (B=1) AND (C=1) ) sont identiques.

Résultats pour ( (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
8
AjV Jsy