W MySQL, jeśli mam listę zakresów dat (początek zakresu i koniec zakresu). na przykład
10/06/1983 to 14/06/1983
15/07/1983 to 16/07/1983
18/07/1983 to 18/07/1983
Chcę sprawdzić, czy inny zakres dat zawiera JAKIEKOLWIEK zakresy znajdujące się już na liście, jak mam to zrobić?
na przykład
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
Odpowiedzi:
To klasyczny problem i jest łatwiejszy, jeśli odwrócisz logikę.
Dam ci przykład.
Opublikuję tutaj jeden okres i wszystkie różne odmiany innych okresów, które w jakiś sposób się pokrywają.
z drugiej strony pozwól mi opublikować wszystkie te, które się nie pokrywają:
Więc jeśli po prostu zredukujesz porównanie do:
wtedy znajdziesz wszystkie te, które się nie pokrywają, a potem znajdziesz wszystkie niepasujące okresy.
W ostatnim przykładzie NIE NA LIŚCIE widać, że pasuje do tych dwóch reguł.
Będziesz musiał zdecydować, czy następujące okresy znajdują się w twoich zakresach, czy poza nimi:
Jeśli Twoja tabela zawiera kolumny o nazwach range_end i range_start, oto kilka prostych instrukcji SQL do pobrania wszystkich pasujących wierszy:
Zwróć uwagę na NIE w tym miejscu. Ponieważ dwie proste reguły znajdują wszystkie niepasujące wiersze, proste NOT odwróci to, mówiąc: jeśli nie jest to jeden z niepasujących wierszy, musi to być jeden z pasujących wierszy .
Stosując tutaj prostą logikę odwrócenia, aby pozbyć się NOT, a otrzymasz:
źródło
Biorąc przykładowy zakres od 06.06.1983 do 18.06.1983 i zakładając, że masz kolumny o nazwie początek i koniec dla swoich zakresów, możesz użyć takiej klauzuli
tj. sprawdź, czy początek zakresu testowego przypada przed końcem zakresu bazy danych i czy koniec zakresu testowego przypada po lub na początku zakresu bazy danych.
źródło
Jeśli Twój RDBMS obsługuje funkcję OVERLAP (), staje się to trywialne - nie ma potrzeby tworzenia własnych rozwiązań. (W Oracle najwyraźniej działa, ale nie jest udokumentowane).
źródło
Mówisz o swoich oczekiwanych wynikach
06.06.1983 do 18.06.1983 = NA LIŚCIE
Jednak okres ten nie zawiera ani nie jest zawarty w żadnym z okresów w Twojej tabeli (nie na liście!) Okresów. Nakłada się on jednak na okres od 10.06.1983 do 14.06.1983.
Przydatna może się okazać książka Snodgrass ( http://www.cs.arizona.edu/people/rts/tdbbook.pdf ): poprzedza ona mysql, ale pojęcie czasu się nie zmieniło ;-)
źródło
Stworzyłem funkcję do rozwiązania tego problemu w MySQL. Po prostu przekonwertuj daty na sekundy przed użyciem.
źródło
Spójrz na poniższy przykład. Będzie ci to pomocne.
źródło
Wypróbuj to na MS SQL
źródło
źródło
Inna metoda wykorzystująca instrukcję BETWEEN sql
Okresy obejmują:
Wyłączone okresy:
źródło
źródło