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

Hvordan sammenligner jeg overlappende værdier inden for en række?

Shahkalpesh besvarede spørgsmålet med:

Jeg skrev en kommentar om, at jeg anser dette for at være forkert, med et par modeksempler:

I et svar på min kommentar anmodede Shahkalpesh om:

Fair nok - ja. Lidt redigeret siger spørgsmålet:

  • fra kl. 07.00 til kl. 13.00, eller
  • fra kl. 9.00 til kl. 13.00, eller
  • fra 9.00 til 17.00.

Nok baggrund. Vi kan se bort fra datoen for aftalerne, og bare overveje tidspunkterne. Jeg går ud fra, at der er en nem måde at begrænse de optagede tider til tt:mm-format; ikke alle DBMS giver faktisk det, men udvidelsen til at håndtere tt:mm:ss er triviel.

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

Givet en søgning efter aftaler, der overlapper intervallet 09:00 - 13:00, bliver Shahkalpeshs (forenklede) forespørgsel:

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

Dette vil returnere alle seks rækker med data. Det er dog kun række 1, 2, 3, der overlapper tidsperioden 09:00 - 13:00. Hvis række 1, 2 og 3 er de eneste gyldige repræsentative aftaleværdier, giver Shahkalpeshs forespørgsel det rigtige svar. Men hvis række 4 (som jeg mener er plausibelt gyldig) er tilladt, så skal den ikke returneres. På samme måde skal række 5 og 6 - hvis de findes - ikke returneres. [Faktisk, forudsat timeStart <= timeEnd for alle rækker i tabellen (og der er ingen NULL-værdier til at ødelægge tingene), kan vi se, at Shahkalpeshs forespørgsel vil returnere ENHVER række data for 09:00-13:00 forespørgslen, fordi enten starttidspunktet for rækken er større 09:00 eller sluttidspunktet er mindre end 13:00 eller begge dele. Dette er ensbetydende med at skrive 1 = 1 eller enhver anden tautologi i WHERE-klausulen. ]

Hvis vi betragter ShaneD's forespørgsel (som forenklet):

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

vi ser, at den også vælger række 1, 2 og 3, men den afviser række 4 (fordi timeStart> '13:00'), 5 (fordi timeEnd <'09:00') og 6 (fordi timeStart> '13:00'). Dette udtryk er et arketypisk eksempel på, hvordan man vælger rækker, der 'overlapper', tæller 'møder' og 'opfyldt af' (se "Allens intervalalgebra ", for eksempel) som overlappende. Ændring af '>=' og '<=' ændrer det sæt af intervaller, der tælles som overlappende.



  1. MYSQL - Sammenlign NU() og en dato i Paris TimeZone i en anmodning

  2. Tjek og optimer MySQL-databasen automatisk med Crontab/Cron

  3. Optimering af en SELECT-forespørgsel, der kører langsomt på Oracle, som kører hurtigt på SQL Server

  4. codeigniter - database:hvordan man opdaterer flere tabeller med en enkelt opdateringsforespørgsel