sql >> Databáze >  >> RDS >> PostgreSQL

Jak ověřit překrývající se časy v Rails pomocí postgresql

V PostgreSQL nemusíte znovu objevovat kolo, existují dvě implementované jednoduché metody, jak dosáhnout kontroly překrývání:

  1. SQL OVERLAPS operátor :

Dost jednoduché,

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

To však umožňuje, aby jeden rozsah byl přesně za druhým
(jinými slovy, kontroluje počátek <=čas ).

  1. Typy rozsahů && (překrývá se) operátor :

I to je obvykle jednoduché. PostgreSQL však nemá vestavěný typ rozsahu pro time (existují však tsrange , tstzrange a daterange pro ostatní časové typy).

Tento typ rozsahu si musíte vytvořit sami:

CREATE TYPE timerange AS RANGE (subtype = time);

Poté však můžete zkontrolovat překrývání pomocí

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

Výhody typů rozsahů:

  • můžete se ovládat, jak chcete zacházet s hranicemi rozsahu

    např. můžete použít timerange(start_at, end_at, '[]') zahrnout jak počáteční, tak koncový bod rozsahů. Ve výchozím nastavení zahrnuje začátek, ale nezahrnuje koncový bod rozsahů.

  • lze jej indexovat, např. s

    CREATE INDEX events_times_idx ON events USING GIST (timerange(start_at, end_at));
    
  • Omezení vyloučení :toto je v podstatě totéž, čeho chcete dosáhnout, ale bude to vynuceno na úrovni DB (např. UNIQUE nebo jakákoli jiná omezení):

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


  1. Nelze se připojit k místnímu PostgreSQL

  2. Jak udělat RAND() deterministický v SQL Server

  3. Vyberte MYSQL ve stejné tabulce

  4. Způsobeno:java.lang.NoSuchMethodError:org.postgresql.core.BaseConnection.getEncoding()Lorg/postgresql/core/Encoding;