PostgreSQL query to detect overlapping time ranges

后端 未结 2 1734
一向
一向 2020-12-16 15:17

I have a table in PostgreSQL 9.2 that looks like this (simplified):

CREATE TABLE my_features
(
  id integer NOT NULL,
  feature_id integer NOT NULL,
  begin_         


        
2条回答
  •  感动是毒
    2020-12-16 16:21

    This can indeed be done using range types.

    The following selects all those rows that do have overlapping ranges:

    select f1.*
    from my_features f1
    where exists (select 1
                  from my_features f2
                  where tsrange(f2.begin_time, f2.end_time, '[]') && tsrange(f1.begin_time, f1.end_time, '[]')
                    and f2.feature_id = f1.feature_id
                    and f2.id <> f1.id);
    

    When you change the condition to NOT EXISTS you'll find those that don't have any overlapping ranges.

    SQLFiddle example: http://sqlfiddle.com/#!15/40b1e/1

    tsrange(f2.begin_time, f2.end_time, '[]') creates a range that includes the upper and lower bounds. You can also create ranges that exclude either one or both.

    More details can be found in the manual:
    http://www.postgresql.org/docs/current/static/rangetypes.html#RANGETYPES-INCLUSIVITY

    The && operator checks if the two ranges overlap: http://www.postgresql.org/docs/current/static/functions-range.html

    (I just wish Oracle had something fancy like that...)

提交回复
热议问题