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

MySQL-Abfrage für einen bestimmten Datumsbereich

Es ist erstaunlich, dass dies seit fast zwei Jahren niemandem aufgefallen ist, aber die anderen Antworten sind alle falsch weil sie den Fall nicht berücksichtigt haben, wenn sowohl das Startdatum als auch das Enddatum außerhalb des Suchbereichs liegen. Betrachten Sie dies als den Bereich des Datums:

start_date <<---------------------------- date range --------------------------->> end_date

Und das ist der Bereich unserer Suche:

start_date <<---------------------------- date range --------------------------->> end_date

                 start_search <<-------- search range -------->> end_search

Die Suche sollte uns ein positives Ergebnis liefern, da sie sich überschneiden. Wenn Sie jedoch die anderen Antworten verwenden, erhalten Sie ein negatives Ergebnis, da weder start_date noch end_date liegt zwischen start_search und end_search .

Um die Lösung zu erhalten, zeichnen wir alle 4 möglichen Modi Schnittpunkt:

                  start_date <<---------- date range --------------------------->> end_date

start_search <<------------------------- search range -------->> end_search
start_date <<---------------------------- date range ---------->> end_date

               start_search <<---------- search range ------------------------>> end_search
start_date <<---------------------------- date range --------------------------->> end_date

                 start_search <<-------- search range -------->> end_search
                 start_date <<----------- date range -------->> end_date

start_search <<------------------------- search range ------------------------>> end_search

Sie können OR alle 4 möglichen Fälle, um die einfache Lösung zu erhalten:

select*from table where

   /* 1st case */ start_date between start_search and end_search         
or /* 2nd case */  end_date  between start_search and end_search         
or /* 3rd case */ (start_date <= start_search and end_date >= end_search)
or /* 4th case */ (start_date >= start_search and end_date <= end_search)

/* the 4th case here is actually redundant since it is being covered by the 1st and 2nd cases */

Eine weniger einfache Lösung ist:

select*from table where

    start_date  between start_search and end_search /* covers 1st and 4th cases */          
or start_search between  start_date  and  end_date  /* covers 2nd and 3rd cases */

Versuchen Sie, es mithilfe der Diagramme oben zu visualisieren.

Wenn wir versuchen, ein Muster aus den 4 obigen Diagrammen zu extrapolieren, können wir das während einer Kreuzung sehen, end_date ist immer >= start_search , und auf der anderen Seite start_date ist immer <= end_search . In der Tat können wir bei weiterer Visualisierung sehen, dass wenn diese beiden Bedingungen gelten, wir keinen Schnittpunkt haben können .

Daher ist eine andere Lösung so einfach wie:

select*from table where

end_date >= start_search && start_date <= end_search

Und der Vorteil dieser Lösung ist, dass wir nur 2 Vergleiche benötigen. Vergleichen Sie das mit dem "OR alles"-Ansatz, der 2 bis zu 8 (3 + 3 + 2) Vergleiche erfordert. (Jeder between Aufruf besteht aus 3 Vergleichen .)