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:
x
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.