2009-04-08 6 views
6

Ich habe eine Event-Tabelle, die einen Datumsbereich mit start_date und end_date Felder angibt. Ich habe einen anderen Datumsbereich, der im Code angegeben ist und die aktuelle Woche als "week_start" und "week_end" definiert.Wie kann man feststellen, ob ein Datumsbereich jederzeit in einem anderen Datumsbereich auftritt?

Ich möchte alle Ereignisse für die Woche abfragen. Die Fälle zu sein scheinen:

  • Ereignis beginnt und endet in der Woche
  • Ereignis vor der Woche beginnt, endet aber im Laufe der Woche
  • Ereignis innerhalb der Woche beginnt, endet aber nach der Woche
  • Veranstaltung beginnt vor der Woche und endet auch nach der Woche
  • Events, dass weder Wohnsitz innerhalb, noch überlappen die Woche überhaupt ignoriert werden

Ich versuche, eine Abfrage zu erstellen, die all diese Fälle behandeln kann. Bis jetzt konnte ich nur Fälle bekommen, die die Überschneidungen der Woche behandeln, oder Ereignisse, die vollständig intern sind; Im Wesentlichen zu viele Datensätze oder gar keine.

+0

Dies ist ein Duplikat von http://stackoverflow.com/questions/325933/determine-wether-two-date-ranges-overlap, das eine strenge Herleitung der einfachen (nur 2 Bedingungen) Lösung hat. –

Antwort

21

In einfachen Worten, entweder eine Woche beginnt während des Ereignisses oder ein Ereignis beginnt während der Woche.

Lassen Sie uns es überprüfen:

Ereignis beginnt und endet in der Woche

Die Veranstaltung in der Woche beginnt.

Ereignis beginnt vor der Woche, sondern endet in der Woche

Die Woche während der Veranstaltung beginnt.

Veranstaltung beginnt in der Woche, aber endet nach der Woche

Die Veranstaltung in der Woche beginnt.

Ereignis beginnt, bevor die Woche und endet auch nach der Woche

Die Woche während der Veranstaltung beginnt.

Beachten Sie, dass BETWEEN in Ausdrücken nur aus Gründen der Kürze verwendet wird.

Strenge Ausdruck sieht wie folgt aus:

(event.start >= week.start AND event.start < week.end) 
OR 
(week.start >= event.start AND week.start < event.end) 

, vorausgesetzt, dass week.end ein week.start + INTERVAL 7 DAY ist.

I. e. wenn Sie Woche beginnt der Sun, 0:00:00, dann sollte es auf next Sun, 0:00:00 (nicht auf Sat, 0:00:00) Ende

Dieser Ausdruck sieht komplexer als die eine, die häufig verwendet wird:

event.start < week.end AND event.end > week.start 

, aber die erstere ist effizienter und index freundlich.

Sehen Sie diese Artikel in meinem Blog für Leistungsvergleiche:

+1

Zwischen hier ist nur für die Kürze. In der Regel sollte das Wochenende ein strenger sein. – Quassnoi

+0

Schade, dass dies das Problem der Ereignisse, die vor der Woche beginnen und nach der Woche enden, nicht lösen wird. –

+0

@Pop Catalin: Wirklich? Beginnt die fragliche Woche nicht während der Veranstaltung? – Quassnoi

3

Sie Ihren Zustand so schreiben könnte:

start_date <= week_end AND end_date >= week_start 

Edit: dies setzt voraus, start_date < = end_date und week_start < = week_end (richtig bestellt) und gibt Ihnen die beste Leistung bei den meisten db Implementierungen aufgrund nicht mit OR (die auf einigen Datenbanken Performance-Probleme schaffen kann)

EDIT2 : Diese Lösung löst auch das Problem von Ereignissen, die vor dem Intervall beginnen und nach dem Intervall enden.

+1

Viel schönere Lösung als zwischen Intervallvergleich –

0

Um ...

where start_date >= week_start and end_date <= week_end 
where start_date <= week_start and end_date >= week_start and end_date <= week_end 
where start_date >= week_start and start_date <= week_end and end_date > week_end 
where start_date < week_start and end_date > week_end 
0

(end2> = Start1) & & (start2 < = end1) Ich denke, würde für alle schneidende Datumsbereiche true zurück.

Ich fand eine Diskussion über diese here, die ich nützlich fand.

2

+1 für Pop Catalin, aber leider habe ich kein Stimmrecht.

Die Einschränkungsbedingung, die Sie möchten, ist nur die Standardmethode, um Allens "OVERLAPS" -Operator auszudrücken.

Zusätzlicher SQL-Vorbehalt: Wenn end_date NULL-Werte zulässig sind, müssen Nullen in diesen Spalten als "das Ende der Zeit" behandelt werden.

Zusätzliche Funktionseinschränkung: Stellen Sie sicher, dass die Verwendung von '< =' im Vergleich zu '<' darauf abgestimmt ist, ob die aufgezeichneten Zeiträume das Enddatum enthalten oder nicht.