sql >> Databasteknik >  >> RDS >> Mysql

Jämföra datumintervall

Detta är ett klassiskt problem, och det är faktiskt lättare om du vänder på logiken.

Låt mig ge dig ett exempel.

Jag kommer att publicera en tidsperiod här, och alla olika varianter av andra perioder som överlappar varandra på något sätt.

           |-------------------|          compare to this one
               |---------|                contained within
           |----------|                   contained within, equal start
                   |-----------|          contained within, equal end
           |-------------------|          contained within, equal start+end
     |------------|                       not fully contained, overlaps start
                   |---------------|      not fully contained, overlaps end
     |-------------------------|          overlaps start, bigger
           |-----------------------|      overlaps end, bigger
     |------------------------------|     overlaps entire period

å andra sidan, låt mig lägga upp alla de som inte överlappar:

           |-------------------|          compare to this one
     |---|                                ends before
                                 |---|    starts after

Så om du enkelt minskar jämförelsen till:

starts after end
ends before start

sedan hittar du alla de som inte överlappar, och sedan hittar du alla perioder som inte matchar.

För ditt sista NOT I LIST-exempel kan du se att det matchar dessa två regler.

Du måste bestämma om följande perioder är INOM eller UTANFÖR dina intervall:

           |-------------|
   |-------|                       equal end with start of comparison period
                         |-----|   equal start with end of comparison period

Om din tabell har kolumner som heter range_end och range_start, här är några enkla SQL för att hämta alla matchande rader:

SELECT *
FROM periods
WHERE NOT (range_start > @check_period_end
           OR range_end < @check_period_start)

Observera NOT där inne. Eftersom de två enkla reglerna hittar alla icke-matchande rader, kommer ett enkelt NOT att vända det för att säga:om det inte är en av de icke-matchande raderna, måste det vara en av de matchande .

Om du använder enkel omkastningslogik här för att bli av med NOT och du kommer att sluta med:

SELECT *
FROM periods
WHERE range_start <= @check_period_end
      AND range_end >= @check_period_start


  1. Återställa en ackumulerad summa?

  2. Ge behörigheter till en MySQL-användare på Linux via kommandoraden

  3. MaxScale Basic Management med MaxCtrl för MariaDB Cluster - Del två

  4. Det går inte att masslasta. Operativsystem felkod 5 (Åtkomst nekad.)