Получать взаиморасчеты из записей. используя 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;

Вывод:

enter image description here

Код MySQL workbench:

с расчетом в виде

(выберите

идентификатор сотрудника, начальный баланс, изменение, дата транзакции_ (начальный баланс + изменение) КАК конечный баланс

из транзакций

где employee_id = 101

упорядочивать по дате транзакции_)

выберите * из расчета;

Вернуться на верх