powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / вычитывание по очереди до нуля - остаток
3 сообщений из 3, страница 1 из 1
вычитывание по очереди до нуля - остаток
    #39968592
zindur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
попалась мне тут задачка, думал с курсором, но думаю есть и другие варианты :)
* совершается иногда покупка на определенную сумму (каждый раз когда покупается создается ячейка/склад) = "Purchase"
* совершается со временем продажа = "Sale"

- условие, при транзакции Sale, сумма вчитывается сначала с первой покупки пока в той ячейки/склад есть остаток
если мало осталось то снимаем до нуля и переходим на следующую ячейку/склад.

- надо узнать остаток на время транзакции в каждой ячейки

Код: 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.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
drop table if exists #WorkingTable

SELECT IDENTITY(int, 1, 1) as RowNumber , TradeType,	cAST(TradeDate as DateTime) as TradeDate
, CAST(Amount AS float) as Amount
, case when TradeType = 'Purchase' THEN 
	Row_NUmber () over (partition by TradeType order by TradeDate ) 
	ELSE NULL
	END PoolId
into #WorkingTable
FROM (
VALUES 
('Purchase',	'1/31/2020',13234589.20)
,('Sale',	'1/31/2020',	1000000.00)
,('Sale',	'1/31/2020',	1000000.00)
,('Sale',	'1/31/2020',	1000000.00)
,('Sale',	'1/31/2020',	1234589.20)
,('Sale',	'1/31/2020',	1000000.00)
,('Sale',	'1/31/2020',	1500000.00)
,('Sale',	'1/31/2020',	1000000.00)
,('Purchase',	'2/28/2020',	2000000.00)
,('Sale',	'2/28/2020',	1000000.00)
,('Sale',	'2/28/2020',	1000000.00)
,('Sale',	'3/6/2020',		2750000.00)
,('Purchase',	'3/11/2020',	2000000.00)
,('Purchase',	'3/12/2020',	2000000.00)
,('Sale',	'3/12/2020',	2000000.00)
,('Purchase',	'3/17/2020',	3000000.00)
,('Sale',	'3/17/2020',	1000000.00)

) AS vtable 
( TradeType,	TradeDate,	Amount)

;WITH cte as (
select *
,  CASE WHEN TradeType ='Purchase' THEN 
		cast(RowNumber as varchar) + '_Purchase'
		ELSE NULL
	END	as Pivot_Purchase_left
, CASE WHEN TradeType ='Sale' THEN 
		Amount * -1
		ELSE NULL
	END	as Sale
from #WorkingTable
)
select *
from 
(
  select *
  from cte
) src
pivot
(
  sum(Amount)
  for Pivot_Purchase_left in ([1_Purchase], [2_Purchase], [3_Purchase], [4_Purchase], [5_Purchase])
) piv
order by TradeDate




спасибо :)

PS: сервер 2016
...
Рейтинг: 0 / 0
вычитывание по очереди до нуля - остаток
    #39968694
PizzaPizza
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zindur,

у вас в начале скользящий итог, который удобнее делать оконными функциями

Код: 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.
30.
31.
32.
with a as(
SELECT *
FROM (
VALUES 
(1,'Purchase',	'1/31/2020',13234589.20)
,(2,'Sale',	'1/31/2020',	1000000.00)
,(3, 'Sale',	'1/31/2020',	1000000.00)
,(4, 'Sale',	'1/31/2020',	1000000.00)
,(5, 'Sale',	'1/31/2020',	1234589.20)
,(6, 'Sale',	'1/31/2020',	1000000.00)
,(7, 'Sale',	'1/31/2020',	1500000.00)
,(8, 'Sale',	'1/31/2020',	1000000.00)
,(9, 'Purchase',	'2/28/2020',	2000000.00)
,(10, 'Sale',	'2/28/2020',	1000000.00)
,(11, 'Sale',	'2/28/2020',	1000000.00)
,(12, 'Sale',	'3/6/2020',		2750000.00)
,(13, 'Purchase',	'3/11/2020',	2000000.00)
,(14, 'Purchase',	'3/12/2020',	2000000.00)
,(15, 'Sale',	'3/12/2020',	2000000.00)
,(16, 'Purchase',	'3/17/2020',	3000000.00)
,(17, 'Sale',	'3/17/2020',	1000000.00)

) AS vtable 
( id, TradeType,	TradeDate,	Amount)),
b as 
(
    select id, TradeType, TradeDate, 
    case WHEN TradeType='Sale' THEN Amount*(-1) ELSE Amount END as Amount
    from a
)

select *, sum(amount) over (order by id) from b



кстати для денег float лучше не использовать, decimal для этого есть

и TradeDate не содержит достаточной точности для сортировки, так как у вас важен порядок операций и в одну дату может быть несколько операций, которые не поделятся по дате.
...
Рейтинг: 0 / 0
вычитывание по очереди до нуля - остаток
    #39970264
zindur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
примерно так должно получится...
Вычитывать - с первой не нулевой транзакции (Purchase) (пока есть остаток) - Sale
Если Purchase - дошел до нуля - переходим на следующий Purchase
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / вычитывание по очереди до нуля - остаток
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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