I would like to find out if I have overlapping time slices that have the same id and the same name. In the following example, the entries with id=2 and name=c overlaps. Entry with id=1 is just for demonstration of a good case.
Given table:
+---+------+-------+------------+--------------+ |id | name | value | validFrom | validTo | +---+------+-------+------------+--------------+ |1 | a | 12 | 2019-01-01 | 9999-12-31 | |1 | b | 34 | 2019-01-01 | 2019-10-31 | |1 | b | 35 | 2019-11-01 | 9999-12-31 | |1 | c | 13 | 2019-01-01 | 2025-12-31 | |2 | a | 49 | 2019-01-01 | 9999-12-31 | |2 | b | 99 | 2019-01-01 | 2034-12-31 | |2 | c | 75 | 2019-01-01 | 2019-10-31 | |2 | c | 84 | 2019-10-28 | 9999-12-31 | |n | ... | ... | ... | ... | +---+------+-------+------------+--------------+
expected output:
+---+------+ |id | name | +---+------+ |2 | c | +---+------+
Thanks for your help in advance!
Advertisement
Answer
You can get the overlapping rows using exists
:
select t.* from t where exists (select 1 from t t2 where t2.id = t.id and t2.name = t.name and t2.value <> t.value and t2.validTo > t.validFrom and t2.validFrom < t.validTo );
If you just want the id
/name
combinations:
select distinct t.id, t.name from t where exists (select 1 from t t2 where t2.id = t.id and t2.name = t.name and t2.value <> t.value and t2.validTo > t.validFrom and t2.validFrom < t.validTo );
You can also do this with a cumulative max:
select t.* from (select t.*, max(validTo) over (partition by id, name order by validFrom rows between unbounded preceding and 1 preceding ) as prev_validTo from t ) t where prev_validTo >= validFrom;