Vous n'avez pas besoin de réinventer la roue dans PostgreSQL, il existe deux méthodes simples implémentées pour réaliser des vérifications de chevauchement :
- SQL
OVERLAPS
opérateur :
Assez simple,
where("(start_at, end_at) OVERLAPS (?, ?)", range.first, range.last)
Cependant, cela permet à une plage d'être exactement après l'autre
(en d'autres termes, il vérifie start <=time
C'est simple aussi, généralement. Mais PostgreSQL n'a pas de type de plage intégré pour time
(cependant il y a tsrange
, tstzrange
, et daterange
pour les autres types temporels).
Vous devez créer vous-même ce type de plage :
CREATE TYPE timerange AS RANGE (subtype = time);
Mais après cela, vous pouvez vérifier le chevauchement avec
where("timerange(start_at, end_at) && timerange(?, ?)", range.first, range.last)
Avantages des types de gamme :
-
vous pouvez vous contrôler, comment voulez-vous gérer les limites de plage
ex. vous pouvez utiliser
timerange(start_at, end_at, '[]')
pour inclure à la fois le début et le point final des plages. Par défaut, il inclut le début, mais exclut le point final des plages. -
il peut être indexé, p.ex. avec
CREATE INDEX events_times_idx ON events USING GIST (timerange(start_at, end_at));
-
Contraintes d'exclusion :c'est essentiellement la même chose, ce que vous voulez réaliser, mais cela sera appliqué au niveau de la base de données (comme,
UNIQUE
ou toute autre contrainte) :ALTER TABLE events ADD CONSTRAINT events_exclude_overlapping EXCLUDE USING GIST (timerange(start_at, end_at) WITH &&);