sql >> Databasteknik >  >> RDS >> Mysql

MySQL-fråga för ett visst datumintervall

Det är fantastiskt att ingen har lagt märke till detta på nästan två år, men de andra svaren är alla fel eftersom de inte tog hänsyn till fallet när både startdatum och slutdatum faller utanför räckvidden för sökintervallet. Tänk på att detta är datumintervallet:

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

Och detta är omfattningen av vår sökning:

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

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

Sökningen bör ge oss ett positivt resultat eftersom de skär varandra. Men om du använder de andra svaren skulle du få ett negativt resultat eftersom varken start_date inte heller end_date är mellan start_search och end_search .

För att få lösningen, låt oss rita alla fyra möjliga lägen av korsningen:

                  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

Du kan OR alla 4 möjliga fall för att få den enkla lösningen:

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 */

En mindre enkel lösning är:

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 */

Försök att visualisera det med hjälp av diagrammen ovan.

Om vi ​​försöker extrapolera ett mönster av de fyra diagrammen ovan kan vi se att under en korsning, end_date är alltid >= start_search , och på baksidan, start_date är alltid <= end_search . När vi visualiserar ytterligare kan vi se att när dessa två villkor gäller kan vi inte ha en korsning .

Som sådan är en annan lösning så enkel som:

select*from table where

end_date >= start_search && start_date <= end_search

Och fördelen med denna lösning är att vi bara behöver 2 jämförelser. Jämför det med "OR allt"-metoden som kräver från 2 upp till så mycket som 8 (3 + 3 + 2) jämförelser. (Varje between samtalet består av 3 jämförelser .)



  1. Hur utför man en SQLite-fråga i en Android-applikation?

  2. Java PreparedStatement hämtar senast infogade ID

  3. World Backup Day:Hur och när ska du säkerhetskopiera din databas?

  4. Minimalt exempel på användning av select... för uppdatering för att isolera rader