Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Benötigen Sie Hilfe bei der richtigen SQL

Überprüfen Sie die Rangfolge zwischen AND und OR.

In der Arithmetik hat die Multiplikation Vorrang vor der Addition.

Beispiel:10+10*10 =110, aber (10+10)*10 =200.

Ähnlich verhält es sich mit AND und OR. AND hat Vorrang vor OR, also ohne Klammern:

WHERE BookingInfo.BookingDate = '05-18-2010' AND BookingInfo.ClinicID = '1' 
  OR BookingInfo.ClinicID = '2'

funktioniert so:

WHERE (BookingInfo.BookingDate = '05-18-2010' AND BookingInfo.ClinicID = '1') 
  OR BookingInfo.ClinicID = '2'

Aber Sie möchten, dass es so funktioniert:

WHERE BookingInfo.BookingDate = '05-18-2010' AND 
  (BookingInfo.ClinicID = '1' OR BookingInfo.ClinicID = '2')

Setzen Sie also die Klammern ein, um sicherzustellen, dass die Rangfolge so funktioniert, wie Sie es möchten.

Ich habe auch gerade bemerkt, dass Sie Datumsangaben im Format MM-TT-JJJJ verwenden, das von MySQL nicht für Datumsliterale erkannt wird. Sie müssen das Format JJJJ-MM-TT verwenden. Das könnte ein anderes Problem verursachen.

SELECT DATE('05-18-2010'); -- returns NULL
SELECT DATE('2010-05-18'); -- returns 2010-05-18

Zu Ihrem Kommentar:

Ja, ich bin sicher, UND hat eine höhere Priorität als ODER. Zum einen ist hier die Rangordnung aller Operatoren in MySQL dokumentiert:http://dev.mysql.com/doc/refman/5.1/en/operator-precedence.html

Lassen Sie uns anhand Ihres ursprünglich genannten Problems ein Beispiel durchgehen:

BookingDate   ClinicID 
2010-05-18    2
2008-05-18    2

WHERE BookingInfo.BookingDate = '2010-05-18' AND 
  BookingInfo.ClinicID = '1' OR BookingInfo.ClinicID = '2'

Mit diesem Ausdruck sollte nur die erste Zeile übereinstimmen. Aber Sie haben festgestellt, dass beide Zeilen übereinstimmen, obwohl das Datum der zweiten Zeile nicht stimmt. Wieso den? Lassen Sie uns jeden Vergleich entweder durch TRUE oder FALSE ersetzen:

TRUE AND FALSE OR TRUE
FALSE AND FALSE OR TRUE

Wenn OR eine höhere Priorität hätte, würde es wie folgt ausgewertet werden:

TRUE AND (FALSE OR TRUE)
FALSE AND (FALSE OR TRUE)

Da jeder mit OR TRUE kombinierte Wert TRUE ergibt, würde der Teilausdruck innerhalb dieser Klammern zu:

reduziert
TRUE AND (TRUE)
FALSE AND (TRUE)

Und die zweite Zeile würde nicht übereinstimmen, weil FALSE AND TRUE FALSE ergibt. Aber das kann nicht sein, da Sie die zweite Zeile falsch gefunden haben.

Tatsächlich hat AND einen höheren Vorrang als OR, sodass es wirklich so ausgewertet wird, als ob der AND-Unterausdruck in Klammern eingeschlossen wäre:

(TRUE AND FALSE) OR TRUE
(FALSE AND FALSE) OR TRUE

Was sich reduziert auf:

(FALSE) OR TRUE
(FALSE) OR TRUE

In beiden Fällen ergibt FALSCH ODER WAHR WAHR und beide Zeilen stimmen überein.

Ohne Klammern ist also die Standardsemantik, dass UND Vorrang vor ODER hat. Sie benötigen die Klammern:

WHERE BookingInfo.BookingDate = '2010-05-18' AND 
  (BookingInfo.ClinicID = '1' OR BookingInfo.ClinicID = '2')