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 und all die verschiedenen Variationen anderer Zeiträume veröffentlichen, 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 einfach den Vergleich reduzieren auf:
starts after end
ends before start
Dann finden Sie alle, die sich nicht überlappen, und dann finden Sie alle nicht übereinstimmenden Zeiträume.
In Ihrem letzten NOT IN LIST-Beispiel können Sie sehen, dass es diesen beiden Regeln entspricht.
Sie müssen entscheiden, ob die folgenden Zeiträume IN 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 enthält, finden Sie hier einige einfache SQL-Anweisungen zum Abrufen aller übereinstimmenden Zeilen:
SELECT *
FROM periods
WHERE NOT (range_start > @check_period_end
OR range_end < @check_period_start)
Beachten Sie das NICHT dort. Da die beiden einfachen Regeln alle nicht übereinstimmenden Zeilen finden, wird sie durch ein einfaches NICHT umgekehrt, um zu sagen: Wenn es sich nicht um eine der nicht übereinstimmenden Zeilen handelt, muss es eine der übereinstimmenden sein .
Wenn Sie hier eine einfache Umkehrlogik anwenden, um das NICHT loszuwerden, erhalten Sie:
SELECT *
FROM periods
WHERE range_start <= @check_period_end
AND range_end >= @check_period_start