Получать взаиморасчеты из записей. используя SQL
Как сгенерировать взаиморасчеты для конкретного сотрудника в SQL?
У меня есть таблица, в которой я отслеживаю взаиморасчеты по сотрудникам. Таблица содержит следующие столбцы:
employee_id
: Идентификационный номер сотрудникаamount
: Сумма транзакции (может быть положительной или отрицательной, в зависимости от причины)reason
: Описание транзакцииcreated_at
: Временная метка, когда произошла транзакция
Мне нужно сгенерировать отчет, показывающий, как баланс сотрудника меняется с течением времени, вот так:
Start Balance | Change | Final Balance |
---|---|---|
0 | +50 | 50 |
50 | -15 | 35 |
35 | +10 | 45 |
45 | -5 | 40 |
Мой SQL-запрос (работает не так, как ожидалось)
Я попытался использовать оконную функцию для расчета предыдущего баланса, изменения и окончательного баланса, но результаты неверны:
SELECT
id,
employee_id,
COALESCE(LAG(SUM(amount)) OVER (ORDER BY created_at ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING), 0) AS prev_amount,
amount AS change,
SUM(amount) OVER (ORDER BY created_at ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS final_amount
FROM settlement_settlement
GROUP BY id
ORDER BY created_at;
Функция LAG(SUM(сумма)) работает не так, как ожидалось, поскольку SOME(сумма) является агрегатной функцией, а функция LAG() работает с отдельными строками. Вместо этого вам следует использовать LAG(final_balance) ПО СРАВНЕНИЮ С (...), чтобы получить суммарную сумму предыдущей строки.
CREATE TABLE employee_settlement ( employee_id int, amount int, created_at date);
insert into employee_settlement values(1,950,'2024-12-01');
insert into employee_settlement values(1,1000,'2025-01-01');
insert into employee_settlement values(1,1050,'2025-02-01');
Фактический запрос :
WITH balance_cte AS (
SELECT
employee_id,
created_at,
amount AS change,
SUM(amount) OVER (PARTITION BY employee_id ORDER BY created_at) AS final_balance
FROM employee_settlement
WHERE employee_id = 1 -- Replace with a specific employee_id
)
SELECT
employee_id,
COALESCE(LAG(final_balance) OVER (PARTITION BY employee_id ORDER BY created_at), 0) AS start_balance,
change,
final_balance
FROM balance_cte
ORDER BY created_at;
Вывод:
Код MySQL workbench:
с расчетом в виде
(выберите
идентификатор сотрудника, начальный баланс, изменение, дата транзакции_ (начальный баланс + изменение) КАК конечный баланс
из транзакций
где employee_id = 101
упорядочивать по дате транзакции_)
выберите * из расчета;