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

¿Cómo comparo valores superpuestos dentro de una fila?

Shahkalpesh respondió a la pregunta con:

Publiqué un comentario que considero que esto está mal, dando un par de contraejemplos:

En respuesta a mi comentario, Shahkalpesh solicitó:

Bastante justo - sí. Ligeramente editada, la pregunta dice:

  • de 7 a. m. a 1 p. m., o
  • de 9 a. m. a 1 p. m., o
  • de 9 a. m. a 5 p. m.

Suficiente fondo. Podemos ignorar la fecha de las citas y solo considerar los horarios. Supongo que hay una manera fácil de limitar los tiempos grabados al formato hh:mm; no todos los DBMS en realidad proporcionan eso, pero la extensión para manejar hh:mm:ss es trivial.

Appointments

Row     timeStart   timeEnd   Note
  1     07:00       13:00     First valid range
  2     09:00       13:00     Second valid range
  3     09:00       17:00     Third valid range
  4     14:00       17:00     First plausibly valid range
  5     05:00       06:00     First probably invalid range
  6     18:00       22:30     Second probably invalid range

Dada una búsqueda de citas que se superponen en el intervalo de 09:00 a 13:00, la consulta (simplificada) de Shahkalpesh se convierte en:

SELECT * FROM Appointments
    WHERE (timeStart >= '09:00' OR timeEnd <= '13:00')

Esto devolverá las seis filas de datos. Sin embargo, solo las filas 1, 2 y 3 se superponen al período de tiempo de 09:00 a 13:00. Si las filas 1, 2 y 3 son los únicos valores de nombramiento de representante válidos, la consulta de Shahkalpesh produce la respuesta correcta. Sin embargo, si la fila 4 (que creo que es plausiblemente válida) está permitida, entonces no debería devolverse. Del mismo modo, las filas 5 y 6, si están presentes, no deben devolverse. [En realidad, suponiendo timeStart <= timeEnd para todas las filas de la tabla (y no hay valores NULL que estropeen las cosas), podemos ver que la consulta de Shahkalpesh devolverá CUALQUIER fila de datos para la consulta 09:00-13:00 porque la hora de inicio de la fila es mayor a las 09:00 o la hora de finalización es menor a las 13:00 o ambas. Esto equivale a escribir 1 = 1 o cualquier otra tautología en la cláusula WHERE. ]

Si consideramos la consulta de ShaneD (simplificada):

SELECT * FROM Appointments
    WHERE timeStart <= '13:00' AND timeEnd >= '09:00'

vemos que también selecciona las filas 1, 2 y 3, pero rechaza las filas 4 (porque timeStart> '13:00'), 5 (porque timeEnd <'09:00') y 6 (porque timeStart> '13:00'). Esta expresión es un ejemplo arquetípico de cómo seleccionar filas que se 'superponen', contando 'cumple' y 'encontrado por' (ver "Álgebra de intervalos de Allen ", por ejemplo) como superpuestos. Cambiar '>=' y '<=' altera el conjunto de intervalos contados como superpuestos.