Mysql
 sql >> Database >  >> RDS >> Mysql

MySQL Query per un determinato intervallo di date

È incredibile che nessuno se ne accorga da quasi due anni, ma le altre risposte sono tutte sbagliate perché non hanno tenuto conto del caso in cui sia la data di inizio che la data di fine non rientrano nell'ambito dell'intervallo di ricerca. Considera che questo è l'intervallo della data:

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

E questo è il raggio della nostra ricerca:

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

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

La ricerca dovrebbe darci un risultato positivo perché si intersecano. Ma se usi le altre risposte, otterresti un risultato negativo perché né start_dateend_date è tra start_search e end_search .

Per ottenere la soluzione, disegniamo tutte e 4 le possibili modalità di incrocio:

                  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

Puoi OR tutti e 4 i casi possibili per ottenere la soluzione semplice:

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

Una soluzione meno semplice è:

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

Prova a visualizzarlo usando i diagrammi sopra.

Se proviamo a estrapolare uno schema dai 4 diagrammi sopra, possiamo vedere che durante un'intersezione, end_date è sempre >= start_search , e sul rovescio, start_date è sempre <= end_search . In effetti, visualizzando ulteriormente, possiamo vedere che quando queste due condizioni sono valide, non possiamo non avere un'intersezione .

In quanto tale, un'altra soluzione è semplice come:

select*from table where

end_date >= start_search && start_date <= end_search

E il vantaggio di questa soluzione è che abbiamo bisogno solo di 2 confronti. Confrontalo con "OR tutto" approccio che richiede da 2 fino a 8 (3 + 3 + 2) confronti. (Ogni between la chiamata consiste in 3 confronti .)