2009-08-06 12 views
113

Czy poniższe dwa stwierdzenia są równoważne?Pierwszeństwo SQL Server Operator: And i Lub

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

i

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

Czy istnieje jakiś tabeli prawdy można używać do sprawdzenia tego?

+0

TRY T T F (T lub T), F lub T (T i F). Czytelnik kodu powinien wyraźnie widzieć intencję pisarza kodu. A scenarzysta musi mieć pewność, że maszyna robi to, co zamierzał. Nawiasy wyrównują wszystkie trzy: czytnik, program piszący i maszynę. :) –

Odpowiedz

191

And ma pierwszeństwo przed Or, więc nawet jeśli a <=> a1 Or a2

Where a And b 

nie jest taka sama jak

Where a1 Or a2 And b, 

ponieważ byłyby wykonywane jako

Where a1 Or (a2 And b) 

i co chcesz, aby były takie same, to

Where (a1 Or a2) And b 

Oto przykład, aby zilustrować:

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

Ouy ... dziękuję ... cieszę się, że zadałem to pytanie :) Oto kilka dalszych odnośników, które mówią dokładnie to samo: http://www.praetoriate.com/t_garmany_easysql_sql_logical_operators.htm Czas użycia niektóre nawiasy. –

+10

Dobrą praktyką jest używanie nawiasów, nawet jeśli nie są potrzebne. bardzo niewielu programistów (jeśli istnieją) zna pierwszeństwo wszystkich dostępnych operatorów. – Trismegistos

+0

@Trismegistos Szkoda, że ​​to nie było takie ... to nie powinno tak być, ale zgaduję, że masz rację. –

26

dodam 2 punkty:

  • "IN" RNO skutecznie szeregowych z nawiasami wokół nich
  • i ma pierwszeństwo ponad LUB w każdym języku, który znam:

Tak więc, 2 wyrażenia po prostu nie są równe.

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 

Tak więc, po złamaniu klauzuli IN, dzieli się szeregowy ORs i zmieniła pierwszeństwo.

+0

gbn Czy w Oracle ORACLE istnieje powiązanie? JEŚLI TAK, w jaki sposób i gdzie mogę uzyskać łączność wszystkich operatorów? – UnKnown

+1

Tak bardzo, jak boli mnie to powiedzieć, I nie ma pierwszeństwa nad OR w rubinach! Żeby było jeszcze gorzej, && * ma * pierwszeństwo przed ||! Jednym z powodów, dla których nie lubię rubinów - dla mnie jest to naruszenie zasady najmniejszego zdziwienia. 2.2.1: 007> true lub true i false => false 2.2.1: 008> true || true && false => prawda –

14
  1. arytmetyczne operatory
  2. operatorem konkatenacji
  3. warunki Porównanie
  4. IS [NIE] NULL, jak, [NIE] W
  5. [NIE] Pomiędzy
  6. Nie równa
  7. NOT logiczny warunek:
  8. I stan logiczny
  9. LUB logiczny warunek

Możesz użyć nawiasów, aby nadpisać reguły pierwszeństwa.

5

Zapytanie pokazać 3-zmienną logiczną tablicę prawdy wyrażenie:

;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 

wyników dla (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 

wyników dla (A=1) OR ((B=1) AND (C=1)) są takie same.

wyników dla ((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