Rivedere l'ordine di precedenza tra AND e OR.
In aritmetica, la moltiplicazione ha una precedenza maggiore dell'addizione.
Esempio:10+10*10 =110, ma (10+10)*10 =200.
È simile con AND e OR. AND ha una precedenza maggiore di OR, quindi senza parentesi:
WHERE BookingInfo.BookingDate = '05-18-2010' AND BookingInfo.ClinicID = '1'
OR BookingInfo.ClinicID = '2'
funziona così:
WHERE (BookingInfo.BookingDate = '05-18-2010' AND BookingInfo.ClinicID = '1')
OR BookingInfo.ClinicID = '2'
Ma vuoi che funzioni in questo modo:
WHERE BookingInfo.BookingDate = '05-18-2010' AND
(BookingInfo.ClinicID = '1' OR BookingInfo.ClinicID = '2')
Quindi inserisci tra parentesi per assicurarti che l'ordine di precedenza funzioni come desideri.
Ho anche appena notato che stai usando le date nel formato MM-GG-AAAA, che non è riconosciuto da MySQL per le date letterali. È necessario utilizzare il formato AAAA-MM-GG. Questo potrebbe causare un problema diverso.
SELECT DATE('05-18-2010'); -- returns NULL
SELECT DATE('2010-05-18'); -- returns 2010-05-18
Re il tuo commento:
Sì, sono sicuro che AND ha una precedenza maggiore di OR. Per prima cosa, la gerarchia di precedenza di tutti gli operatori in MySQL è documentata qui:http://dev.mysql.com/doc/refman/5.1/en/operator-precedence.html
Esaminiamo un esempio usando il tuo problema originariamente dichiarato:
BookingDate ClinicID
2010-05-18 2
2008-05-18 2
WHERE BookingInfo.BookingDate = '2010-05-18' AND
BookingInfo.ClinicID = '1' OR BookingInfo.ClinicID = '2'
Usando questa espressione, solo la prima riga dovrebbe corrispondere. Ma hai scoperto che entrambe le righe corrispondono, anche se la data della seconda riga non è corretta. Come mai? Sostituiamo ogni confronto con VERO o FALSO:
TRUE AND FALSE OR TRUE
FALSE AND FALSE OR TRUE
Se OR avesse una precedenza maggiore, valuterebbe in questo modo:
TRUE AND (FALSE OR TRUE)
FALSE AND (FALSE OR TRUE)
Poiché qualsiasi valore combinato con OR TRUE restituisce TRUE, la sottoespressione all'interno di queste parentesi si ridurrebbe a:
TRUE AND (TRUE)
FALSE AND (TRUE)
E la seconda riga non corrisponderebbe, perché FALSO E VERO restituisce FALSO. Ma non può essere, dal momento che hai trovato che la seconda riga corrisponde in modo errato.
In effetti, AND ha una precedenza maggiore di OR, quindi valuta davvero come se avessi parentesi attorno alla sottoespressione AND:
(TRUE AND FALSE) OR TRUE
(FALSE AND FALSE) OR TRUE
Che si riduce a:
(FALSE) OR TRUE
(FALSE) OR TRUE
In entrambi i casi, FALSE O TRUE restituisce TRUE ed entrambe le righe corrispondono.
Quindi, senza parentesi, la semantica predefinita è che AND ha una precedenza maggiore di OR. Ti servono le parentesi:
WHERE BookingInfo.BookingDate = '2010-05-18' AND
(BookingInfo.ClinicID = '1' OR BookingInfo.ClinicID = '2')