Dein Beispiel ist aber dann auch falsch, da fehlt im gezeigten Ergebnis der Eintrag für “05.91.2017 a 1 1”.
Ich gehe mal davon aus, daß das ein kontinuierlicher Prozess ist und Du eigentlich IMMER willst, daß auch bei neu eingegebenen Daten diese ‘Zusammenfassung’ schon gleich mit erfolgt, oder?
create table infromi2(von_bis daterange, id char, c1 int, c2 int);
Diese Tabelle hat nun gleich ein Feld von_bis, das das gültige Datum anzeigt. Ich gehe mal davon aus, daß Dir Range-Typen bekannt sind.
Für die Eingabe von Daten verwendest Du von nun an eine Funktion:
create or replace function insert_infromi2(in _date date, in _id char, in _c1 int, in _c2 int) returns bool as $$
declare r infromi2%rowtype;
_von_bis daterange;
begin
select * from infromi2 where von_bis @> _date - 1 and id = _id and c1 = _c1 and c2 = _c2 into r;
if found then
update infromi2 set von_bis = daterange(lower(r.von_bis),_date,'[]') where von_bis @> _date - 1 and id = _id and c1 = _c1 and c2 = _c2 ;
else
_von_bis := daterange(_date,_date+1);
insert into infromi2 values(_von_bis,_id,_c1,_c2);
end if;
return true;
end; $$language plpgsql;
Demo:
test=*# select insert_infromi2('2017-01-01'::date,'a',1,1);
insert_infromi2
-----------------
t
(1 Zeile)
test=*# select insert_infromi2('2017-01-02'::date,'a',1,1);
insert_infromi2
-----------------
t
(1 Zeile)
test=*# select insert_infromi2('2017-01-03'::date,'a',1,1);
insert_infromi2
-----------------
t
(1 Zeile)
test=*# select insert_infromi2('2017-01-04'::date,'a',2,1);
insert_infromi2
-----------------
t
(1 Zeile)
test=*# select insert_infromi2('2017-01-05'::date,'a',1,1);
insert_infromi2
-----------------
t
(1 Zeile)
test=*# select insert_infromi2('2017-01-01'::date,'b',2,2);
insert_infromi2
-----------------
t
(1 Zeile)
test=*# select insert_infromi2('2017-01-02'::date,'b',2,1);
insert_infromi2
-----------------
t
(1 Zeile)
test=*# select * from infromi2;
von_bis | id | c1 | c2
-------------------------+----+----+----
[2017-01-01,2017-01-04) | a | 1 | 1
[2017-01-04,2017-01-05) | a | 2 | 1
[2017-01-05,2017-01-06) | a | 1 | 1
[2017-01-01,2017-01-02) | b | 2 | 2
[2017-01-02,2017-01-03) | b | 2 | 1
(5 Zeilen)
Ach ja: damit das ganze auch bei größeren Datenmengen noch performant ist, erstellen wir die Tabelle gleich mit passenden Index und einem Constraint, der verhindert, daß sich Einträge überlappen:
create table infromi2(von_bis daterange, id char, c1 int, c2 int, exclude using gist(von_bis with &&, id with =));
Das kann man noch zuende würzen, indem man dem User das Insert und Update - Recht auf die Tabelle entzieht und die Funktion als User mit diesen rechten erstellt und diese als security definer markiert. Auch den Rückgabewert der Funktion kann noch angepaßt werden, daß er z.B. anzeigt, ob es nun letztendlich ein Insert oder ein Update war.