Vorrang des SQL-Logikoperators: Und und oder


177

Sind die beiden folgenden Aussagen gleichwertig?

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

und

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

Gibt es eine Art Wahrheitstabelle, mit der ich dies überprüfen könnte?


4
Versuchen Sie: TT F. (T oder T) und F. T oder (T und F). Der Leser von Code sollte die Absicht des Codeschreibers klar erkennen können. Und der Autor muss sicher sein, dass die Maschine das tut, was er beabsichtigt hat. Klammern richten alle drei aus: Leser, Schreiber und Maschine. :)
Assad Ebrahim

Antworten:


286

Andhat Vorrang vor Or, auch wenna <=> a1 Or a2

Where a And b 

ist nicht dasselbe wie

Where a1 Or a2 And b,

denn das würde ausgeführt werden als

Where a1 Or (a2 And b)

und was Sie wollen, um sie gleich zu machen, ist das Folgende (mit Klammern, um Vorrangregeln zu überschreiben):

 Where (a1 Or a2) And b

Hier ist ein Beispiel zur Veranschaulichung:

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

Für diejenigen, die Referenzen konsultieren möchten (in alphabetischer Reihenfolge):


18
Es wird empfohlen, Klammern zu verwenden, auch wenn sie nicht benötigt werden. Nur sehr wenige Programmierer (falls vorhanden) kennen den Vorrang aller verfügbaren Operatoren.
Trismegistos

1
@Trismegistos Ich wünschte, es wäre nicht so ... es sollte nicht so sein, aber ich vermute, Sie haben Recht.
Charles Bretana

1
Dieser ANDdann ORVorrang ist Teil des SQL - Standard?
Jaime Hablutzel

@Jaime, Ja, und afaik, es ist auch Teil des Standards für alle Programmiersprachen.
Charles Bretana

4
@Bsienn, Sie sind sich nicht sicher, was Sie getan haben, aber das widerspricht dem Standard-SQL und der MySQL-Dokumentation ... dev.mysql.com/doc/refman/5.0/de/operator-precedence.html Sie sollten es erneut versuchen - vorsichtig Zeit ... versuchen 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 select case when (@x=1 or @y=1) and @z=1 then'T' else 'F' end
Charles Bretana

33

Ich werde 2 Punkte hinzufügen:

  • "IN" ist effektiv ein serielles ODER mit Klammern
  • UND hat in jeder Sprache, die ich kenne, Vorrang vor ODER

Die beiden Ausdrücke sind also einfach nicht gleich.

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

Wenn Sie also die IN-Klausel auflösen, teilen Sie die seriellen ORs auf und ändern die Priorität.


gbn Gibt es Assoziativität in ORACLE SQL? WENN JA, wie und wo kann ich dann die Assoziativität aller Operatoren erhalten?
Asif Mushtaq

2
So sehr es mich auch schmerzt, es zu sagen, UND hat keinen Vorrang vor ODER in Rubin! Um die Sache noch schlimmer zu machen, && hat Vorrang vor ||! Einer der Gründe, warum ich Rubin nicht mag - es verstößt für mich immer wieder gegen das Prinzip des geringsten Erstaunens. 2.2.1: 007> wahr oder wahr und falsch => falsch 2.2.1: 008> wahr || true && false => true
Alex L

23
  1. Rechenzeichen
  2. Verkettungsoperator
  3. Vergleichsbedingungen
  4. IST [NICHT] NULL, WIE [NICHT] IN
  5. [NICHT ZWISCHEN
  6. Nicht gleichzusetzen mit
  7. NICHT logische Bedingung
  8. UND logische Bedingung
  9. ODER logische Bedingung

Sie können Klammern verwenden, um Vorrangregeln zu überschreiben.


9

Abfrage zum Anzeigen einer Wahrheitstabelle mit 3 Variablen für boolesche Ausdrücke:

;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

Ergebnisse für (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

Die Ergebnisse für (A=1) OR ( (B=1) AND (C=1) )sind gleich.

Ergebnisse für ( (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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.