Чтобы получить скользящий баланс, вы можете SUM
суммы (до текущей строки включительно), основанные на том, был ли id
получателем или отправителем:
SELECT id, sender_id, recipient_id, amount_money,
SUM(CASE WHEN recipient_id = 2 THEN amount_money
WHEN sender_id = 2 THEN -amount_money
END) OVER (ORDER BY id) AS balance
FROM transactions
Вывод:
id sender_id recipient_id amount_money balance
1 1 2 60.00 60.00
2 1 2 15.00 75.00
3 2 1 35.00 40.00
Если вам нужен массив, вы можете использовать array_agg
с вышеуказанным запросом в качестве производной таблицы:
SELECT array_agg(balance)
FROM (
SELECT SUM(CASE WHEN recipient_id = 2 THEN amount_money
WHEN sender_id = 2 THEN -amount_money
END) OVER (ORDER BY id) AS balance
FROM transactions
) t
Вывод:
[60,75,40]
Демонстрация на dbfiddle
Если вы хотите быть более сложным и поддерживать сальдо для нескольких учетных записей, вам нужно разделить исходные данные на идентификаторы учетных записей, добавив, когда идентификатор является получателем, и вычтя, когда отправитель. Вы можете использовать CTE
s для генерации соответствующих данных:
WITH trans AS (
SELECT id, sender_id AS account_id, -amount_money AS amount
FROM transactions
UNION ALL
SELECT id, recipient_id AS account_id, amount_money AS amount
FROM transactions
),
balances AS (
SELECT id, account_id, ABS(amount),
SUM(amount) OVER (PARTITION BY account_id ORDER BY id) AS balance
FROM trans
)
SELECT account_id, ARRAY_AGG(balance) AS bal_array
FROM balances
GROUP BY account_id
Вывод:
account_id bal_array
1 [-60,-75,-40]
2 [60,75,40]
Демонстрация на dbfiddle