sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur man validerar överlappande tider i Rails med postgresql

Du behöver inte uppfinna hjulet på nytt i PostgreSQL, det finns två implementerade enkla metoder för att uppnå överlappningskontroller:

  1. SQL:s OVERLAPS operatör :

Enkelt nog,

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

Detta gör det dock möjligt för ett intervall att ligga exakt efter det andra
(med andra ord kontrollerar det start <=tid ).

  1. Räckviddstyper' && (överlappar) operatör :

Detta är också enkelt, vanligtvis. Men PostgreSQL har ingen inbyggd intervalltyp för time (men det finns tsrange , tstzrange och daterange för de andra tidstyperna).

Du måste skapa den här intervalltypen för dig själv:

CREATE TYPE timerange AS RANGE (subtype = time);

Men efter detta kan du kontrollera överlappning med

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

Fördelar med intervalltyper:

  • du kan kontrollera dig själv, hur vill du hantera räckviddsgränser

    t.ex. du kan använda timerange(start_at, end_at, '[]') för att inkludera både start- och slutpunkten för intervallen. Som standard inkluderar den starten, men exkluderar slutpunkten för intervallen.

  • den kan indexeras, t.ex. med

    CREATE INDEX events_times_idx ON events USING GIST (timerange(start_at, end_at));
    
  • Uteslutningsbegränsningar :detta är i huvudsak detsamma, vad du vill uppnå, men det kommer att tillämpas på DB-nivå (som, UNIQUE eller andra begränsningar):

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


  1. MySQL hittar toppresultat för varje grupp

  2. Påverkar kolumnordning prestanda i Microsoft SQL Server 2012?

  3. AWS Python Lambda med Oracle - OID Generation misslyckades även efter att ha lagt till HOSTALIASES

  4. Java PreparedStatement hämtar senast infogade ID