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