sql >> Databasteknik >  >> RDS >> Mysql

Behöver hjälp med korrekt SQL

Granska prioritetsordningen mellan OCH och ELLER.

I aritmetiken har multiplikation högre företräde än addition.

Exempel:10+10*10 =110, men (10+10)*10 =200.

Det är liknande med OCH och ELLER. AND har högre prioritet än OR, så detta utan parentes:

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

fungerar så här:

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

Men du vill att det ska fungera så här:

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

Så sätt inom parentes för att se till att prioritetsordningen fungerar som du vill.

Jag har också märkt att du använder datum i formatet MM-DD-ÅÅÅÅ, som inte känns igen av MySQL för datumbokstavar. Du måste använda formatet ÅÅÅÅ-MM-DD. Det kan orsaka ett annat problem.

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

Angående din kommentar:

Ja, jag är säker på att OCH har högre prioritet än ELLER. För det första är prioriteringshierarkin för alla operatörer i MySQL dokumenterad här:http://dev.mysql.com/doc/refman/5.1/en/operator-precedence.html

Låt oss gå igenom ett exempel med ditt ursprungligen angivna problem:

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

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

Med detta uttryck ska bara den första raden matcha. Men du upptäckte att båda raderna matchar, även om datumet för den andra raden inte stämmer. Varför? Låt oss ersätta varje jämförelse med antingen TRUE eller FALSE:

TRUE AND FALSE OR TRUE
FALSE AND FALSE OR TRUE

Om OR hade högre prioritet skulle det utvärderas så här:

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

Eftersom alla värden kombinerat med OR TRUE ger TRUE, skulle underuttrycket inom dessa parenteser reduceras till:

TRUE AND (TRUE)
FALSE AND (TRUE)

Och den andra raden skulle inte matcha, eftersom FALSE AND TRUE ger FALSE. Men det kan inte vara det, eftersom du hittade den andra raden felaktigt matchande.

Faktum är att AND har högre prioritet än OR, så det utvärderas verkligen som om du hade parenteser runt AND-underuttrycket:

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

Vilket reduceras till:

(FALSE) OR TRUE
(FALSE) OR TRUE

I båda fallen ger FALSE ELLER TRUE TRUE, och båda raderna matchar.

Så utan parentes är standardsemantiken att AND har högre prioritet än ELLER. Du behöver parenteserna:

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


  1. Kan jag återställa en transaktion som jag redan har genomfört? (dataförlust)

  2. MySQL får en konversation mellan två användare

  3. Tabellnamnsdilemma:Singular vs. pluralnamn

  4. MySQL vad är den maximala storleken på en databas?