Wenn ich in MySQL eine Liste von Datumsbereichen habe (Bereichsstart und Bereichsende). z.B
10/06/1983 to 14/06/1983
15/07/1983 to 16/07/1983
18/07/1983 to 18/07/1983
Und ich möchte überprüfen, ob ein anderer Datumsbereich einen der bereits in der Liste enthaltenen Bereiche enthält. Wie würde ich das tun?
z.B
06/06/1983 to 18/06/1983 = IN LIST
10/06/1983 to 11/06/1983 = IN LIST
14/07/1983 to 14/07/1983 = NOT IN LIST
Antworten:
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.
Lassen Sie mich andererseits alle diejenigen posten, die sich nicht überschneiden:
Wenn Sie also einfach den Vergleich reduzieren auf:
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:
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:
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:
quelle
Wenn Sie Ihren Beispielbereich vom 06.06.1983 bis zum 18.06.1983 verwenden und davon ausgehen, dass Sie Spalten mit den Namen Start und Ende für Ihre Bereiche haben, können Sie eine Klausel wie diese verwenden
Überprüfen Sie also, ob der Beginn Ihres Testbereichs vor dem Ende des Datenbankbereichs liegt und ob das Ende Ihres Testbereichs nach oder am Anfang des Datenbankbereichs liegt.
quelle
Wenn Ihr RDBMS die Funktion OVERLAP () unterstützt, ist dies trivial - es sind keine selbst entwickelten Lösungen erforderlich. (In Oracle funktioniert es anscheinend, ist aber nicht dokumentiert).
quelle
In Ihren erwarteten Ergebnissen sagen Sie
06/06/1983 bis 18/06/1983 = IN LIST
Dieser Zeitraum enthält jedoch keinen der Zeiträume in Ihrer Tabelle (keine Liste!) Von Zeiträumen und ist auch nicht in diesen enthalten. Es überschneidet sich jedoch mit dem Zeitraum 10/06/1983 bis 14/06/1983.
Vielleicht finden Sie das Snodgrass-Buch ( http://www.cs.arizona.edu/people/rts/tdbbook.pdf ) nützlich: Es datiert vor MySQL, aber das Konzept der Zeit hat sich nicht geändert ;-)
quelle
Ich habe eine Funktion erstellt, um dieses Problem in MySQL zu lösen. Konvertieren Sie die Daten einfach vor der Verwendung in Sekunden.
quelle
Schauen Sie sich das folgende Beispiel an. Es wird für Sie hilfreich sein.
quelle
Versuchen Sie dies unter MS SQL
quelle
quelle
Eine andere Methode mit der Anweisung BETWEEN sql
Zeiträume enthalten:
Ausgeschlossene Zeiträume:
quelle
quelle