Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Datumsbereiche vergleichen

Dies ist ein klassisches Problem, und es ist tatsächlich einfacher, wenn Sie die Logik umkehren.

Lassen Sie mich Ihnen ein Beispiel geben.

Ich werde hier einen Zeitraum posten und all die verschiedenen Variationen anderer Zeiträume, die sich in irgendeiner Weise überschneiden.

           |-------------------|          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

Lassen Sie mich andererseits alle diejenigen posten, die sich nicht überschneiden:

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

Wenn Sie also den Vergleich einfach reduzieren auf:

starts after end
ends before start

dann finden Sie alle, die sich nicht überschneiden, und dann alle nicht übereinstimmenden Punkte.

Für Ihr letztes NOT IN LIST-Beispiel können Sie sehen, dass es diesen beiden Regeln entspricht.

Sie müssen entscheiden, ob die folgenden Zeiträume INNERHALB oder AUSSERHALB Ihrer Bereiche liegen:

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

Wenn Ihre Tabelle Spalten mit den Namen range_end und range_start hat, finden Sie hier ein einfaches SQL, um alle übereinstimmenden Zeilen abzurufen:

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

Beachten Sie das NICHT da drin. Da die beiden einfachen Regeln alle Nichtübereinstimmungen finden Zeilen, ein einfaches NOT wird es umkehren, um zu sagen:Wenn es keine der nicht übereinstimmenden Zeilen ist, muss es eine der übereinstimmenden Zeilen sein .

Wenn Sie hier eine einfache Umkehrlogik anwenden, um das NOT loszuwerden, erhalten Sie am Ende:

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