Mysql
 sql >> Database >  >> RDS >> Mysql

Come faccio a confrontare i valori sovrapposti all'interno di una riga?

Shahkalpesh ha risposto alla domanda con:

Ho postato un commento che ritengo sbagliato, fornendo un paio di controesempi:

In risposta al mio commento, Shahkalpesh ha chiesto:

Abbastanza giusto - sì. Leggermente modificata, la domanda dice:

  • dalle 7:00 alle 13:00 oppure
  • dalle 9:00 alle 13:00 oppure
  • dalle 9:00 alle 17:00.

Abbastanza sfondo. Possiamo ignorare la data degli appuntamenti e considerare solo gli orari. Presumo che ci sia un modo semplice per limitare i tempi registrati al formato hh:mm; in realtà non tutti i DBMS lo forniscono, ma l'estensione per gestire hh:mm:ss è banale.

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

Data una ricerca di appuntamenti che si sovrappongono all'intervallo 09:00 - 13:00, la query (semplificata) di Shahkalpesh diventa:

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

Ciò restituirà tutte e sei le righe di dati. Tuttavia, solo le righe 1, 2, 3 si sovrappongono al periodo di tempo 09:00 - 13:00. Se le righe 1, 2 e 3 sono gli unici valori di appuntamento rappresentativi validi, la domanda di Shahkalpesh produce la risposta corretta. Tuttavia, se la riga 4 (che ritengo plausibilmente valida) è consentita, non dovrebbe essere restituita. Allo stesso modo, le righe 5 e 6, se presenti, non devono essere restituite. [In realtà, presupponendo timeStart <= timeEnd per tutte le righe della tabella (e non ci sono valori NULL per incasinare le cose), possiamo vedere che la query di Shahkalpesh restituirà QUALSIASI riga di dati per la query 09:00-13:00 perché l'ora di inizio di la riga è maggiore delle 09:00 o l'ora di fine è inferiore alle 13:00 o entrambe. Questo equivale a scrivere 1 = 1 o qualsiasi altra tautologia nella clausola WHERE. ]

Se consideriamo la query di ShaneD (come semplificata):

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

vediamo che seleziona anche le righe 1, 2 e 3, ma rifiuta le righe 4 (perché timeStart> '13:00'), 5 (perché timeEnd <'09:00') e 6 (perché timeStart> '13:00'). Questa espressione è un esempio archetipico di come selezionare le righe che 'sovrappongono', contando 'incontra' e 'incontrato da' (vedi "Algebra degli intervalli di Allen ", ad esempio) come sovrapposti. La modifica di '>=' e '<=' altera l'insieme di intervalli conteggiati come sovrapposti.