Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como comparo valores sobrepostos em uma linha?


Shahkalpesh respondeu à pergunta com:

Postei um comentário que considero errado, dando um par de contra-exemplos:

Em resposta ao meu comentário, Shahkalpesh solicitou:

Justo o suficiente - sim. Ligeiramente editada, a pergunta diz:
  • das 7h às 13h, ou
  • das 9h às 13h, ou
  • das 9h às 17h.

Bastante plano de fundo. Podemos ignorar a data dos compromissos e considerar apenas os horários. Estou assumindo que existe uma maneira fácil de limitar os tempos gravados no formato hh:mm; nem todos os DBMS realmente fornecem isso, mas a extensão para lidar com hh:mm:ss é 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 uma busca por compromissos que se sobrepõem ao intervalo 09:00 - 13:00, a consulta (simplificada) de Shahkalpesh se torna:
SELECT * FROM Appointments
    WHERE (timeStart >= '09:00' OR timeEnd <= '13:00')

Isso retornará todas as seis linhas de dados. No entanto, apenas as linhas 1, 2, 3 se sobrepõem ao período de 09:00 - 13:00. Se as linhas 1, 2 e 3 forem os únicos valores de compromisso de representante válidos, a consulta de Shahkalpesh produzirá a resposta correta. No entanto, se a linha 4 (que acho plausivelmente válida) for permitida, ela não deve ser retornada. Da mesma forma, as linhas 5 e 6 - se presentes - não devem ser retornadas. [Na verdade, supondo timeStart <= timeEnd para todas as linhas da tabela (e não há valores NULL para atrapalhar as coisas), podemos ver que a consulta de Shahkalpesh retornará QUALQUER linha de dados para a consulta 09:00-13:00 porque o horário de início de a linha é maior que 09:00 ou o horário de término é menor que 13:00 ou ambos. Isso equivale a escrever 1 = 1 ou qualquer outra tautologia na cláusula WHERE. ]

Se considerarmos a consulta de ShaneD (como simplificada):
SELECT * FROM Appointments
    WHERE timeStart <= '13:00' AND timeEnd >= '09:00'

vemos que ele também seleciona as linhas 1, 2 e 3, mas rejeita as linhas 4 (porque timeStart> '13:00'), 5 (porque timeEnd <'09:00') e 6 (porque timeStart> '13:00'). Essa expressão é um exemplo arquetípico de como selecionar linhas que 'se sobrepõem', contando 'atender' e 'atender por' (consulte "Álgebra intervalar de Allen ", por exemplo) como sobreposição. Alterar '>=' e '<=' altera o conjunto de intervalos contados como sobreposição.