powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Набор суммы для каждого счета.
8 сообщений из 8, страница 1 из 1
Набор суммы для каждого счета.
    #38823900
Hamber
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Задача стоим следующим образом:

Есть список клиентов @ListClient
idclient - его ID
Summa - ту сумму которую необходимо списать.

Есть список его счетов: @listaccbalance

idclient - id клиента
account - номер счета
summaost - сумма остатка
priority - приоритет списания (от 1 до бесконечности)

На выходе нужно для каждого клиента "расписать" сумму для списания с каждого счета.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
DECLARE @ListClient TABLE (idclient int, summa numeric(16,2))

INSERT INTO @listclient
SELECT 1, 500
UNION
SELECT 2, 1000
UNION
SELECT 3, 200
UNION
SELECT 4, 50
UNION
SELECT 5, 700

DECLARE @ListAccBalance TABLE (idclient int, account varchar(20), summaost numeric(16,2), priority int)

INSERT INTO @ListAccBalance
SELECT 1,'1', 600, 1
UNION
SELECT 2,'21',1000,3
UNION
SELECT 2,'22',400,2
UNION
SELECT 2,'23',300,1
UNION
SELECT 3,'3',200,1
UNION
SELECT 4,'4',20,1
UNION
SELECT 5,'5',0,1



Т.е. прежде чем расписывать сумму нужно отсортировать список для каждого клиента по приоритету и затем размазывать сумму.

На выходе нам нужно получить вот такую табличку:

SummaSpis - сумма списания
Comment - для понимания логики работы

IDclientAccountSummaClientPrioritySummaSpisComment116001500Нужно списать 500 т.к. на счет 600 нам нужно только 50022310001300Нужно списать 1000 но на счету только 300 списываем 30022210002400Нужно списать 1000-300=700 но на счету только 400 списываем 40022310003300Нужно списать 1000-300-400=300 но на счету 1000 нам столько не надо списываем 300332001200Нужно 200 и на счету 200 значит списываем 2004450120Нужно 50 но на счету 20 значит списываем 205570010Нужно списать 700 но на счету 0 поэтому 0

Код: sql
1.
2.
SELECT @@VERSION
Microsoft SQL Server 2005 - 9.00.5000.00 (Intel X86)



Объемы примерно 10000 клиентов, у каждого по 1-3 счета.
...
Рейтинг: 0 / 0
Набор суммы для каждого счета.
    #38823957
Edkonst2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hamber,

Шаг 1. Набираете курсор на списание
Шаг 2. В курсоре обрабатываешь списания согласно начислениям по приоритету
Шаг 3. В курсоре меняются остатки на счетах после списания
Шаг 4. Закрываем курсор.
...
Рейтинг: 0 / 0
Набор суммы для каждого счета.
    #38823970
Фотография a_voronin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Edkonst2008Hamber,

Шаг 1. Набираете курсор на списание
Шаг 2. В курсоре обрабатываешь списания согласно начислениям по приоритету
Шаг 3. В курсоре меняются остатки на счетах после списания
Шаг 4. Закрываем курсор.

В транзакцию не забудьте каждое списание обернуть.
...
Рейтинг: 0 / 0
Набор суммы для каждого счета.
    #38824008
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
имхо это перевернутая задача накопительного итога.
В один запрос решается.
...
Рейтинг: 0 / 0
Набор суммы для каждого счета.
    #38824139
londinium
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторимхо это перевернутая задача накопительного итога.
В один запрос решается.
Разве? А перенос остатка? (т.е. на 1-м счете 20 рублей, а мы списываем 100, тогда 80 надо передать на второй счет и т.д. Плюс клиент еще и в плюсе может оказаться :-))
...
Рейтинг: 0 / 0
Набор суммы для каждого счета.
    #38824147
Фотография a_voronin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
londiniumавторимхо это перевернутая задача накопительного итога.
В один запрос решается.
Разве? А перенос остатка? (т.е. на 1-м счете 20 рублей, а мы списываем 100, тогда 80 надо передать на второй счет и т.д. Плюс клиент еще и в плюсе может оказаться :-))

На 2012 я бы еще извернулся в один проход запросом. Но на 2005 что-то идей нет. Только идти курсором и перебирать записи.
...
Рейтинг: 0 / 0
Набор суммы для каждого счета.
    #38824164
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a_voroninlondiniumпропущено...

Разве? А перенос остатка? (т.е. на 1-м счете 20 рублей, а мы списываем 100, тогда 80 надо передать на второй счет и т.д. Плюс клиент еще и в плюсе может оказаться :-))

На 2012 я бы еще извернулся в один проход запросом. Но на 2005 что-то идей нет. Только идти курсором и перебирать записи.
да ладно, многие подобные "курсорные" вещи через рекурсивное cte делается, вот прямо в лоб

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
with cte as (
	select 
		lc.idclient, 
		priority = 0, 
		account = cast(null as varchar(20)),
		lc.summa,
		summatodo = cast(lc.summa as numeric(16, 2)),
		spis = cast(0 as numeric(16, 2))
	from @ListClient as lc
	union all
	select
		lab.idclient,
		lab.priority,
		account = lab.account,
		c.summa,
		summatodo = cast(c.summatodo - v.spis  as numeric(16, 2)),
		spis = cast(v.spis as numeric(16, 2))
	from cte as c
	join @ListAccBalance as lab on lab.idclient = c.idclient and lab.priority = c.priority + 1
	cross apply (
                select case when lab.summaost >= c.summatodo then c.summatodo else lab.summaost end
	) as v(spis)
)
select * 
from cte as c
where c.priority > 0
order by c.idclient, c.priority
...
Рейтинг: 0 / 0
Набор суммы для каждого счета.
    #38824165
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shakill, естественно, в priority не должно быть дырок, иначе предварительно через row_number придется раздать порядок записям
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Набор суммы для каждого счета.
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]