Проблема:
У нас есть таблица транзакций. Все записи в этой таблице имеют один из следующих типов транзакций: пополнение кошелька (платежи), снятие кошелька (продажа) и возврат наличных (скидка, которая будет использоваться для будущих продаж). Я хочу добавить дополнительный столбец в каждую строку, отображающую остаток кешбека. Кэшбэк используется либо для дисконта при новых продажах, либо для уменьшения отрицательного общего баланса.
таблица транзакций:
customer (int)
transaction_date (date)
amount (int)
transaction_type (varchar(25))
Я пытался использовать функцию запаздывания, чтобы получить значение предыдущей строки и использовать ее для вычисления в текущей строке. Но это не всегда работает, потому что функция задержки возвращает назад к строке, на которую она конкретно указала.
с использованием функции отставания в расчете:
case when
isnull(lag(balance_cashback) over (partition by client_id order by transaction_date), 0)
+ case when type = "cashback" then amount else 0 end
+ case when type = "revenu" and amount < 0 then amount else 0 end
<= 0 then 0
else
lag(balance_cashback) over (partition by client_id order by transaction_date)
+ case when type = "cashback" then amount else 0 end
+ case when type = "revenu" and amount < 0 then amount else 0 end
end
Поиск в интернете Думаю, мне следует использовать цикл или, возможно, курсор?
Идея:
Идея состоит в том, чтобы использовать таблицу транзакций и добавить два столбца столбцов. Rowumber для всех строк в таблице транзакций, которые я хочу просмотреть. И второе число на все транзакции каждого клиента. Следующим шагом кажется создание пустой таблицы баланса с полями rownumclient, client_id, total_balance и cashback_balance.
Расчет количества столбцов:
row_number () over (order by client_id, transaction_date) as rownumber_all
row_number () over (partition by client_id order by client_id, transaction_date) as rownumber_client
таблица транзакций с номерами:
rownumber_all (int)
rownumber_client (int)
client (int)
transaction_date (date)
amount (int)
transaction_type (varchar(25))
таблица баланса:
rownumber_client (int)
client_id (int)
overall_balance (int)
cashback_balance (int)
пример таблицы транзакций с номерами:
rownumbwr_all | rownumber_client | client_id | transaction_date | amount | transaction_type
1 1 123 2018-10-12 10 wallet deposit
2 2 123 2018-10-27 5 cashback
3 3 123 2018-11-03 -2,5 wallet withdrawal
4 4 123 2018-11-13 -5 wallet withdrawal
5 5 123 2018-12-18 10 wallet deposit
6 6 123 2018-12-19 20 wallet deposit
7 7 123 2018-12-21 5 cashback
8 1 456 2018-10-11 -45 wallet withdrawal
9 2 456 2018-10-23 5 cashback
10 3 456 2018-11-01 5 cashback
11 4 456 2018-11-04 10 wallet deposit
Etc.
При наличии дополнительных столбцов rownumber и новой таблицы баланса мне нужно создать цикл по всем строкам в таблице транзакций. Использование столбца rownumber_all, чтобы начать с первого. Вновь созданная таблица баланса используется для расчета баланса кешбека в текущей строке. Мы используем эту таблицу с левым соединением с таблицей транзакций со столбцами rownumber. Когда мы перебираем первую строку, таблица баланса пуста, но со второй строки вычисляется остаток кешбека из предыдущей строки.
выберите выписку для расчета текущего кэшбэка:
select
t1.rownumall,
t1.rownumclient,
t1.client_id,
t2.overall_balance + t1.amount as overall_balance,
case
when (t2.overall_balance + case when t1.type = 'cashback' then t1.amount else 0 end) < 0 then 0
when t1.type in (sales, cashback) then amount
else null
end + t2.cashback_balance as cashback_balance
/*insert into balance*/
from
transactions as t1
left join cashback as t2 on t2.client_id = t1.client_id and t2.rownumber_client = t1.rownumber_client-1
Для каждой строки, которая проходит через результат оператора выбора выше, следует вставить в таблицу сальдо, пока есть доступные записи транзакций. И, как уже было сказано, остаток кешбэка либо используется для дисконта при новых продажах, либо для уменьшения отрицательного общего баланса Тем не менее, ожидаемый результат, который я ищу, выглядит следующим образом, а cashback_balance - самое важное поле.
таблица ожидаемых транзакций с остатками:
client_id | transaction_date | amount | transaction_type | overall_balance | cashback balance
123 2018-10-12 10 wallet deposit 10 0
123 2018-10-27 5 cashback 15 5
123 2018-11-03 -2,5 wallet withdrawal 12,5 2,5
123 2018-11-13 -5 wallet withdrawal 7,5 0
123 2018-12-18 10 wallet deposit 17,5 0
123 2018-12-19 20 wallet deposit 37,5 0
123 2018-12-21 5 cashback 42,5 5
456 2018-10-11 -45 wallet withdrawal -2,5 0
456 2018-10-23 5 cashback 2,5 2,5
456 2018-11-01 5 cashback 7,5 7,5
456 2018-11-04 10 wallet deposit 17,5 7,5
Etc.
Я пытался объяснить как можно больше и надеюсь, что идея и ожидаемый результат ясны. Я не могу себе представить, что то, что мне нужно, не было сделано раньше, но я просто не могу найти конкретный вариант использования где-либо.
Итак, какой эксперт по SQL будет достаточно любезен, чтобы сказать мне простым языком, как этого можно добиться, используя цикл, курсор или любой другой способ? Любая помощь будет высоко оценен. Если требуется какое-либо разъяснение, пожалуйста, дайте мне знать.