sql >> Base de Datos >  >> RDS >> Mysql

Comparar intervalos de fechas

Este es un problema clásico, y en realidad es más fácil si inviertes la lógica.

Déjame 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, déjame publicar todos aquellos 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 NO EN LA LISTA, 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 ahí. Dado que las dos reglas simples encuentran todos los no coincidentes filas, un simple NOT lo invertirá para decir:si no es una de las filas que no coinciden, tiene que ser una de las que coinciden .

Aplicando 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