PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come convalidare i tempi di sovrapposizione in Rails con postgresql

Non è necessario reinventare la ruota in PostgreSQL, ci sono due semplici metodi implementati per ottenere i controlli di sovrapposizione:

  1. OVERLAPS di SQL operatore :

Abbastanza semplice,

where("(start_at, end_at) OVERLAPS (?, ?)", range.first, range.last)

Tuttavia, ciò consente a un intervallo di essere esattamente dopo l'altro
(in altre parole, controlla inizio <=ora ).

  1. Tipi di intervallo' && operatore (sovrapposti) :

Anche questo è semplice, di solito. Ma PostgreSQL non ha un tipo di intervallo integrato per time (tuttavia ci sono tsrange , tstzrange e daterange per gli altri tipi temporali).

Devi creare tu stesso questo tipo di intervallo:

CREATE TYPE timerange AS RANGE (subtype = time);

Ma dopo questo, puoi controllare la sovrapposizione con

where("timerange(start_at, end_at) && timerange(?, ?)", range.first, range.last)

Pro dei tipi di gamma:

  • puoi controllarti, come vuoi gestire i limiti dell'intervallo

    ad es. potresti usare timerange(start_at, end_at, '[]') per includere sia l'inizio che il punto finale degli intervalli. Per impostazione predefinita include l'inizio, ma esclude il punto finale degli intervalli.

  • può essere indicizzato, ad es. con

    CREATE INDEX events_times_idx ON events USING GIST (timerange(start_at, end_at));
    
  • Vincoli di esclusione :questo è essenzialmente lo stesso, quello che vuoi ottenere, ma verrà applicato a livello di DB (come, UNIQUE o qualsiasi altro vincolo):

    ALTER TABLE events
      ADD CONSTRAINT events_exclude_overlapping
      EXCLUDE USING GIST (timerange(start_at, end_at) WITH &&);