I have two tables one mentioning the start and end time of an event and corresponding value and other having the value recorded at midnight daily.
CREATE TABLE table1 (
id integer,
date_strt timestamp,
date_end timestamp,
strt_unit integer,
end_unit integer
);
INSERT INTO table1 (id, date_strt, date_end,strt_unit,end_unit)
VALUES
(1, '2023-10-27 12:00:00','2023-10-31 12:00:00', 5,72),
(2, '2023-10-30 12:15:00','2023-11-02 00:00:00', 78,90);
CREATE TABLE table2 (
id integer,
dates timestamp,
unit integer
);
INSERT INTO table2 (id, dates, unit)
VALUES
(1, '2023-10-28 00:00:00', 55),
(1, '2023-10-29 00:00:00', 60),
(1, '2023-10-30 00:00:00', 65),
(1, '2023-10-31 00:00:00', 70),
(2, '2023-10-30 00:00:00', 75),
(2, '2023-10-31 00:00:00', 80),
(2, '2023-11-01 00:00:00', 85),
(2, '2023-11-02 00:00:00', 90);
I want to obtain data set like this where I obtain difference in data of each day at midnight 00:00:00 hours starting from the start date to end date mentioned in table 1 by using the date available at table 2.
id start_time start_value end_time end_value
1, '2023-10-27 12:00:00', 5, '2023-10-28 00:00:00', 55
1, '2023-10-29 00:00:00', 60, '2023-10-29 00:00:00', 60
1, '2023-10-29 00:00:00', 60, '2023-10-30 00:00:00', 65
1, '2023-10-30 00:00:00', 65, '2023-10-31 00:00:00', 70
1, '2023-10-31 00:00:00', 70, '2023-10-31 12:00:00', 72
2, '2023-10-30 12:15:00', 78, '2023-10-31 00:00:00', 80
2, '2023-10-31 00:00:00', 80, '2023-11-01 00:00:00', 85
2, '2023-11-01 00:00:00', 85, '2023-11-02 00:00:00', 90
I planned to generate a date series between the start and end dates using 1 day as interval but could not generate the appropriate dates and hence can’t further use lead or lag in it.
I have added the fiddle link.
2
Answers
Here’s how to do it with the window functions
LAG()
andLEAD()
:Result :
Explanations :
First CTE used to generate ranges between two dates using
generate_series
The second CTE was used to link data with the second table in order to obtain the
end_value
for each range.The third CTE is used to obtain the
start_value
for each range.Demo here
You can join
table2
with the previoustable2
andtable1
and the nexttable2
andtable1
, making sure that there is nothing in between (this is why we join with the *_no_between tables and filter by the *_no_between tables being nulls) and then decide what’s the proper value viacase
–when
.