How to write an SQL query generating a history of the sums of a column at different timestamps?
Consider below approach
select event_timestamp, sum(ifnull(coalesce(x, prev_x), 0)) x_sum
from (
select *,
first_value(x ignore nulls) over(partition by thing_id order by event_timestamp desc rows between 1 following and unbounded following) prev_x
from (
select *
from (select distinct thing_id from events)
cross join (select distinct event_timestamp from events)
left join events using (event_timestamp, thing_id)
)
)
group by event_timestamp
if applied to sample data in your question - output is
Having found explanations of the greatest-n-per-group problem, I think I managed to write a solution. It works fine with the given minimal example, but I'm not 100% sure if it works perfectly in general. (And I guess it can be simplified.)
WITH
events AS (
SELECT 1 AS thing_id, 1 AS x, TIMESTAMP('2021-12-01 00:00:00') AS event_timestamp
UNION ALL
SELECT 1, 3, TIMESTAMP('2021-12-01 00:01:00')
UNION ALL
SELECT 2, 5, TIMESTAMP('2021-12-01 00:02:00')
UNION ALL
SELECT 1, 2, TIMESTAMP('2021-12-01 00:03:00')
UNION ALL
SELECT 1, 0, TIMESTAMP('2021-12-01 00:04:00')
),
state_timestamps AS (
SELECT
event_timestamp state_timestamp
FROM
events),
states AS (
SELECT
thing_id,
state_timestamp,
event_timestamp,
x
FROM
events
CROSS JOIN
state_timestamps
WHERE
event_timestamp <= state_timestamp ),
latest_states AS (
SELECT
a.thing_id,
a.state_timestamp,
a.event_timestamp,
a.x
FROM
states a
INNER JOIN (
SELECT
thing_id,
state_timestamp,
MAX(event_timestamp) event_timestamp
FROM
states
GROUP BY
thing_id,
state_timestamp ) b
ON
a.thing_id = b.thing_id
AND a.event_timestamp = b.event_timestamp
AND a.state_timestamp = b.state_timestamp),
sum_states AS (
SELECT
state_timestamp,
SUM(x) x_sum
FROM
latest_states
GROUP BY
state_timestamp
ORDER BY
state_timestamp)
SELECT
*
FROM
sum_states
Output:
+---------------------+-------+
| state_timestamp | x_sum |
+---------------------+-------+
| 2021-12-01 00:00:00 | 1 |
| 2021-12-01 00:01:00 | 3 |
| 2021-12-01 00:02:00 | 8 |
| 2021-12-01 00:03:00 | 7 |
| 2021-12-01 00:04:00 | 5 |
+---------------------+-------+