Este es un problema clásico, y en realidad es más fácil si inviertes la lógica.
Dejame darte un ejemplo.
Publicaré un período de tiempo aquí y todas las diferentes variaciones de otros períodos que se superponen de alguna manera.
|-------------------| 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
por otro lado, permítanme publicar todos los que no se superponen:
|-------------------| compare to this one
|---| ends before
|---| starts after
Entonces, si simplemente reduce la comparación a:
starts after end
ends before start
luego encontrará todos los que no se superponen, y luego encontrará todos los períodos que no coinciden.
Para su ejemplo final de NOT IN LIST, puede ver que coincide con esas dos reglas.
Deberá decidir si los siguientes períodos están DENTRO o FUERA de sus rangos:
|-------------|
|-------| equal end with start of comparison period
|-----| equal start with end of comparison period
Si su tabla tiene columnas llamadas range_end y range_start, aquí hay un SQL simple para recuperar todas las filas coincidentes:
SELECT *
FROM periods
WHERE NOT (range_start > @check_period_end
OR range_end < @check_period_start)
Tenga en cuenta el NO allí. Dado que las dos reglas simples encuentran todas las filas que no coinciden , un NOT simple lo invertirá para decir: si no es una de las filas que no coinciden, tiene que ser una de las que coinciden .
Aplicando una lógica de inversión simple aquí para deshacerse del NOT y terminará con:
SELECT *
FROM periods
WHERE range_start <= @check_period_end
AND range_end >= @check_period_start