Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment comparer des valeurs qui se chevauchent dans une ligne ?

Shahkalpesh a répondu à la question par :

J'ai posté un commentaire que je considère comme faux, donnant une paire de contre-exemples :

En réponse à mon commentaire, Shahkalpesh a demandé :

Assez juste - oui. Légèrement modifiée, la question indique :

  • de 7h à 13h, ou
  • de 9h à 13h, ou
  • de 9h à 17h.

Assez de fond. Nous pouvons ignorer la date des rendez-vous et ne considérer que les heures. Je suppose qu'il existe un moyen simple de limiter les heures enregistrées au format hh:mm ; tous les SGBD ne fournissent pas cela, mais l'extension pour gérer hh:mm:ss est triviale.

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

Étant donné une recherche de rendez-vous chevauchant la plage 09h00 - 13h00, la requête (simplifiée) de Shahkalpesh devient :

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

Cela renverra les six lignes de données. Cependant, seules les lignes 1, 2, 3 chevauchent la période 09:00 - 13:00. Si les lignes 1, 2 et 3 sont les seules valeurs de rendez-vous représentatives valides, la requête de Shahkalpesh produit la bonne réponse. Cependant, si la ligne 4 (qui, à mon avis, est plausiblement valide) est autorisée, elle ne doit pas être renvoyée. De même, les lignes 5 et 6 - si elles sont présentes - ne doivent pas être renvoyées. [En fait, en supposant timeStart <= timeEnd pour toutes les lignes de la table (et il n'y a pas de valeurs NULL pour gâcher les choses), nous pouvons voir que la requête de Shahkalpesh renverra N'IMPORTE QUELLE ligne de données pour la requête 09:00-13:00 car soit l'heure de début de la ligne est supérieure à 09h00 ou l'heure de fin est inférieure à 13h00 ou les deux. Cela revient à écrire 1 = 1 ou toute autre tautologie dans la clause WHERE. ]

Si nous considérons la requête de ShaneD (telle que simplifiée) :

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

nous voyons qu'il sélectionne également les lignes 1, 2 et 3, mais il rejette les lignes 4 (car timeStart> '13:00'), 5 (car timeEnd <'09:00') et 6 (car timeStart> '13 :00'). Cette expression est un exemple archétypal de la façon de sélectionner des lignes qui "se chevauchent", en comptant "se rencontre" et "se rencontre par" (voir "Algèbre d'intervalle d'Allen ", par exemple) comme se chevauchant. Changer '>=' et '<=' modifie l'ensemble des intervalles comptés comme se chevauchant.