Пока у вас есть способ определить, какие другие строки должны быть включены в «объединенные» данные каждой строки, это просто сделать с LATERAL
.
testdb=# create table t(day date, id bigint, data jsonb);
ERROR: relation "t" already exists
testdb=# select * from t;
day | id | data
------------+----+--------------------
2016-06-20 | 1 | {"key0": "value0"}
2016-06-21 | 1 | {"key1": "value1"}
2016-06-22 | 1 | {"key2": "value2"}
(3 rows)
testdb=# SELECT t0.day,
t0.id,
j
FROM t t0, LATERAL
(SELECT jsonb_object(keys, vals) j
FROM (SELECT array_agg(kvset.key) keys,
array_agg(kvset.value) vals
FROM
(SELECT key, value FROM t t1
CROSS JOIN jsonb_each_text(t1.data) AS r
WHERE t1.day<=t0.day) AS kvset
) AS kvpairs
)_;
day | id | j
------------+----+--------------------------------------------------------
2016-06-20 | 1 | {"key0": "value0"}
2016-06-21 | 1 | {"key0": "value0", "key1": "value1"}
2016-06-22 | 1 | {"key0": "value0", "key1": "value1", "key2": "value2"}
В этом случае я использую t1.day<=t0.day
, чтобы указать, что все строки, равные или меньшие заданной даты, должны быть отсканированы для построения комбинированного объекта для строки этой даты.
Стоит отметить, что я ничего не делаю, чтобы разумно обрабатывать конфликтующие ключи; это, вероятно, не делает правильную вещь, когда он встречает один и тот же ключ в нескольких строках.