#postgresql
Вопрос:
У меня есть следующая таблица:
идентификатор пользователя | дата совершения сделки | day_end_balance |
---|---|---|
523161 | 7/2/2021 | 136.2 |
523161 | 6/14/2021 | 215.4 |
523161 | 6/7/2021 | 0 |
523161 | 6/2/2021 | 440 |
Таким образом, баланс отображается при совершении транзакции, и баланс остается неизменным в конце дня, если транзакция не происходит. Я хочу создать таблицу, которая показывает баланс на конец дня на одного клиента с начала жизни клиента до сегодняшнего дня. Проверьте приведенную ниже таблицу для получения желаемого результата.
идентификатор пользователя | дата совершения сделки | day_end_balance |
---|---|---|
523161 | 6/2/2021 | 440 |
523161 | 6/3/2021 | 440 |
…… | ………… | ….. |
523161 | 6/7/2021 | 0 |
523161 | 6/8/2021 | 0 |
523161 | 6/9/2021 | 0 |
523161 | 6/10/2021 | 0 |
523161 | 6/11/2021 | 0 |
523161 | 6/12/2021 | 0 |
523161 | 6/13/2021 | 0 |
523161 | 6/14/2021 | 215.4 |
523161 | 6/14/2021 | 215.4 |
523161 | 6/15/2021 | 215.4 |
523161 | 6/16/2021 | 215.4 |
523161 | 6/17/2021 | 215.4 |
523161 | 6/18/2021 | 215.4 |
523161 | 6/19/2021 | 215.4 |
523161 | 6/20/2021 | 215.4 |
523161 | 6/21/2021 | 215.4 |
523161 | 6/22/2021 | 215.4 |
523161 | 6/23/2021 | 215.4 |
523161 | 6/24/2021 | 215.4 |
523161 | 6/25/2021 | 215.4 |
523161 | 6/26/2021 | 215.4 |
523161 | 6/27/2021 | 215.4 |
523161 | 6/28/2021 | 215.4 |
523161 | 6/29/2021 | 215.4 |
523161 | 6/30/2021 | 215.4 |
523161 | 7/1/2021 | 215.4 |
523161 | 7/2/2021 | 136.2 |
523161 | …. | 136.2 |
523161 | дата сегодняшнего дня | 136.2 |
Как это сделать в postgres sql? Я знаю, что это будет включать last_value() и coalesce (), и, возможно, lag() и lead(). Но не знаю, как это написать.
Ответ №1:
generate_series()
Вы можете использовать, чтобы получить все дни между минимальным днем для клиента и сегодняшним днем, и присоединиться к этому, выбрав данные самого верхнего дня, меньшего или равного соответствующему дню в серии.
SELECT cjl."customer_id",
gs."transacting date",
cjl."day_end_balance"
FROM generate_series((SELECT min(t."transacting date")
FROM elbat t
WHERE t."customer_id" = 523161),
current_date,
'1 day'::interval) gs
("transacting date")
CROSS JOIN LATERAL (SELECT t."customer_id",
t."day_end_balance"
FROM elbat t
WHERE t."customer_id" = 523161
AND t."transacting date" <= gs."transacting date"
ORDER BY t."transacting date" DESC
LIMIT 1) cjl
ORDER BY gs."transacting date";