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

Confronto di intervalli di date

Questo è un problema classico, ed è più facile invertire la logica.

Ti faccio un esempio.

Pubblicherò qui un periodo di tempo e tutte le diverse varianti di altri periodi che si sovrappongono in qualche modo.

           |-------------------|          compare to this one
               |---------|                contained within
           |----------|                   contained within, equal start
                   |-----------|          contained within, equal end
           |-------------------|          contained within, equal start+end
     |------------|                       not fully contained, overlaps start
                   |---------------|      not fully contained, overlaps end
     |-------------------------|          overlaps start, bigger
           |-----------------------|      overlaps end, bigger
     |------------------------------|     overlaps entire period

d'altra parte, permettimi di pubblicare tutti quelli che non si sovrappongono:

           |-------------------|          compare to this one
     |---|                                ends before
                                 |---|    starts after

Quindi, se riduci semplicemente il confronto a:

starts after end
ends before start

poi troverai tutti quelli che non si sovrappongono e poi troverai tutti i periodi non corrispondenti.

Per il tuo ultimo esempio NOT IN LIST, puoi vedere che corrisponde a queste due regole.

Dovrai decidere se i seguenti periodi sono DENTRO o FUORI dai tuoi intervalli:

           |-------------|
   |-------|                       equal end with start of comparison period
                         |-----|   equal start with end of comparison period

Se la tua tabella ha colonne chiamate range_end e range_start, ecco un semplice SQL per recuperare tutte le righe corrispondenti:

SELECT *
FROM periods
WHERE NOT (range_start > @check_period_end
           OR range_end < @check_period_start)

Nota il NON lì dentro. Poiché le due semplici regole trovano tutti i non corrispondenti righe, un semplice NOT lo invertirà per dire:se non è una delle righe non corrispondenti, deve essere una di quelle corrispondenti .

Applicando qui una semplice logica di inversione per sbarazzarti del NOT e ti ritroverai con:

SELECT *
FROM periods
WHERE range_start <= @check_period_end
      AND range_end >= @check_period_start