sql >> Base de Datos >  >> RDS >> Mysql

Necesito ayuda con SQL correcto

Revise el orden de precedencia entre AND y OR.

En aritmética, la multiplicación tiene mayor precedencia que la suma.

Ejemplo:10+10*10 =110, pero (10+10)*10 =200.

Es similar con AND y OR. AND tiene mayor precedencia que OR, así que esto sin paréntesis:

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

funciona así:

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

Pero quieres que funcione así:

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

Así que pon los paréntesis para asegurarte de que el orden de precedencia funcione como tú quieres.

También noté que está usando fechas en formato MM-DD-YYYY, que MySQL no reconoce para los literales de fecha. Debe utilizar el formato AAAA-MM-DD. Eso podría estar causando un problema diferente.

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

Re tu comentario:

Sí, estoy seguro de que AND tiene mayor precedencia que OR. Por un lado, la jerarquía de precedencia de todos los operadores en MySQL se documenta aquí:http://dev.mysql.com/doc/refman/5.1/en/operator-precedence.html

Veamos un ejemplo usando su problema planteado originalmente:

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

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

Con esta expresión, solo debe coincidir la primera fila. Pero descubrió que ambas filas coinciden, aunque la fecha de la segunda fila no es correcta. ¿Por qué? Reemplacemos cada comparación con VERDADERO o FALSO:

TRUE AND FALSE OR TRUE
FALSE AND FALSE OR TRUE

Si OR tuviera mayor precedencia, se evaluaría así:

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

Dado que cualquier valor combinado con O VERDADERO da como resultado VERDADERO, la subexpresión dentro de estos paréntesis se reduciría a:

TRUE AND (TRUE)
FALSE AND (TRUE)

Y la segunda fila no coincidiría, porque FALSO Y VERDADERO da como resultado FALSO. Pero eso no puede ser, ya que encontró que la segunda fila coincide incorrectamente.

De hecho, AND tiene mayor precedencia que OR, por lo que realmente se evalúa como si tuviera paréntesis alrededor de la subexpresión AND:

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

Lo que se reduce a:

(FALSE) OR TRUE
(FALSE) OR TRUE

En ambos casos, FALSO O VERDADERO da como resultado VERDADERO y ambas filas coinciden.

Entonces, sin paréntesis, la semántica predeterminada es que AND tiene mayor prioridad que OR. Necesitas los paréntesis:

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