I have a simple database table (Postgres) consisting of 3 attributes (f1,f2 and f3) ordered by date. (db<>fiddle).
I want to transform (group?) the result into the following table:
f1 | f2 | f3 | beginn | end |
---|---|---|---|---|
A | A | A | 31.12.2017 | 05.01.2018 |
B | B | B | 06.01.2018 | 10.01.2018 |
A | A | A | 11.01.2018 | 16.01.2018 |
I tried (but obviously failed) with:
SELECT a.f1 ,a.f2 ,a.f3 ,MIN(datum) AS beginn ,MAX(datum) AS end FROM test1 a GROUP BY 1,2,3
I tried a bit with window-functions but that wasn’t leading to anywhere.
Do you have any ideas how I can get to the desired result?
Advertisement
Answer
If you enumerate the rows for each combination of f1
, f2
, and f3
, then subtract that number of days from datum
, then the value will be constant on adjacent days where the three columns are the same.
The rest is just aggregation:
select f1, f2, f3, min(datum), max(datum) from (select t1.*, row_number() over (partition by f1, f2, f3 order by datum) as seqnum from test1 t1 ) t1 group by f1, f2, f3, datum - seqnum * interval '1 day' order by min(datum);
Here is a db<>fiddle.