to nie takie proste zagadnienie jak by się wydawało ale proszę poniżej masz dwie metody obliczenia tej daty w zależności jaką wersje postgresa dysponujesz. Ponieważ nie załączasz struktury bazy sam sobie ją musiałem stworzyć.
(na przyszłość proszę podawaj podstawowe dane)
create table medium (id serial primary key, nazwa varchar(100));
insert into medium (nazwa) values('woda'),('gaz');
create table taryfa (id serial primary key, medium_id integer not null,data_od date not null,data_do date not null,wartosc real not null);
insert into taryfa (medium_id,data_od,data_do,wartosc) values
((select id from medium where nazwa='woda'),'2012-01-01'::date,'2012-01-31'::date,1.0)
,((select id from medium where nazwa='woda'),'2012-02-01'::date,'infinity'::date,2.0)
,((select id from medium where nazwa='gaz'),'2012-01-01'::date,'2012-03-31'::date,5.0)
,((select id from medium where nazwa='gaz'),'2012-04-01'::date,'infinity'::date,6.0);
create table zuzycie (id serial primary key, data timestamp not null , wartosc real not null ,medium_id integer not null);
insert into zuzycie (data,wartosc,medium_id) values
('2012-01-01'::date,1,(select id from medium where nazwa='woda'))
,('2012-02-04'::date,4,(select id from medium where nazwa='woda'))
,('2012-03-08'::date,14,(select id from medium where nazwa='woda'))
,('2012-04-01'::date,20,(select id from medium where nazwa='woda'))
,('2012-01-01'::date,1,(select id from medium where nazwa='gaz'))
,('2012-08-01'::date,1,(select id from medium where nazwa='gaz'));
a tu masz sam finalny select
select z.data
,z.wartosc as zuzycie
,t.wartosc as taryfa
,z.wartosc * t.wartosc as koszt
,lag(z.data,1,null) over(partition by z.medium_id order by z.data) as poprzedni_odczyt_metoda_1
,(select data from zuzycie as s where s.medium_id=z.medium_id and s.data < z. data order by s.data desc limit 1) as poprzedni_odczyt_metoda_2
,z.data-lag(z.data,1,null) over(partition by z.medium_id order by z.data) as uplynelo
from zuzycie z
left join taryfa t on z.medium_id=t.medium_id and z.data between t.data_od and t.data_do
where z.medium_id = (select id from medium where nazwa = 'woda')
order by z.data;
Musisz sobie zdawać sprawę, że trzeba jeszcze oprogramować takie sytuacje jak:
- zużycie (odczyt licznika) nastąpiło gdy kończyła się jedna taryfa, a zaczynała obowiązywać kolejna
- zakres dat w polach data_od i data_do w tabeli taryfa nie mogą się nakładać i powinny być ciągłe (bez przerw)