2009-08-06 8 views
113

Le due istruzioni riportate di seguito sono equivalenti?Precedenza operatore logico SQL: And e O

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 

C'è una sorta di tabella di verità potrei usare per verificare questo?

+0

provare: T T F. (T o T) e F. T o (T e F). Il lettore di codice dovrebbe essere chiaramente in grado di vedere l'intento dello scrittore di codice. E lo scrittore deve essere sicuro che la macchina stia facendo ciò che intendeva. Le parentesi allineano tutte e tre: lettore, scrittore e macchina. :) –

risposta

191

And ha la precedenza su Or, quindi, anche se a <=> a1 Or a2

Where a And b 

non è lo stesso di

Where a1 Or a2 And b, 

perché sarebbe essere eseguita in conformità

Where a1 Or (a2 And b) 

e ciò che si voglio, per renderli uguali, è

Where (a1 Or a2) And b 

Ecco un esempio per illustrare:

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

Ahi ... grazie ... felice di aver fatto questa domanda :) Ecco alcuni ulteriori riferimenti che dice esattamente la stessa cosa: http://www.praetoriate.com/t_garmany_easysql_sql_logical_operators.htm Tempo di utilizzare alcune parentesi. –

+10

È buona norma utilizzare le parentesi anche se non sono necessarie. pochissimi programmatori (se ce ne sono) conoscono la precedenza di tutti gli operatori disponibili. – Trismegistos

+0

@Trismegistos Vorrei che non fosse così ... non dovrebbe essere così, ma suppongo che tu abbia ragione. –

26

sarò aggiungere 2 punti:

  • "IN" è OR efficace di serie con le parentesi intorno a loro
  • e ha la precedenza oltre O in ogni lingua che conosco

Quindi, le 2 espressioni non sono semplicemente uguali.

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 

Così, quando si interrompe la clausola IN up, si dividono le RUP seriali, e cambiato la precedenza.

+0

gbn Esiste associatività in ORACLE SQL? SE SI allora come e dove posso ottenere l'associatività di tutti gli operatori? – UnKnown

+1

Per quanto mi addolori dirlo, E non ha la precedenza su O in rubino! Per peggiorare le cose, && * fa * hanno la precedenza su ||! Una delle ragioni per cui non mi piace il rubino - viola il principio del minimo stupore più e più volte per me. 2.2.1: 007> true o true e false => false 2.2.1: 008> true || true && false => true –

14
  1. operatori aritmetici
  2. operatore di concatenazione
  3. condizioni di confronto
  4. IS [NOT] NULL, LIKE, [NOT] IN
  5. [NOT] TRA
  6. Non uguale a
  7. NON condizione logica
  8. E condizione logica
  9. Condizione OR logica

È possibile utilizzare le parentesi per sovrascrivere le regole di precedenza.

5

query per mostrare a 3 variabile booleana tavolo espressione verità:

;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 

Risultati per (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 

Risultati per (A=1) OR ((B=1) AND (C=1)) sono gli stessi.

Risultati per ((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