Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Ограничение при разноске. / 6 сообщений из 6, страница 1 из 1
25.06.2018, 09:13
    #39665053
Cristiano_Rivaldo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение при разноске.
Всем привет. В ходе разнесения появилась потребность контролировать получившиеся суммы на максимальное значение.

Код: 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.
DECLARE @N_Sum_For_Split  MONEY = 5.2  -- сумма для разнесения 

;WITH t 
(	ID ,				-- идентификатор (PK)
	N_Order,			-- порядок сортировки (для нарастающего итога)
	N_SUM,				-- сумма 
	F_DOC,				-- идентификатор докуменат (FK)				
	N_Sum_Max_By_Doc	-- максимальная сумма в рамках одного документа, которая должна быть после разноски
) AS
(
	SELECT 1,0,3.5,1,4
	UNION ALL
	SELECT 2,1,1.1,1,4
	UNION ALL
	SELECT 3,2,0.8,2,0.4
)

SELECT	t.*,
		CASE WHEN t.N_Need >= 0 THEN  
 					CASE WHEN t.N_Sum <= t.N_Need THEN t.N_Sum ELSE t.N_Need END 			
 		END N_Sum_Res		-- сумма после разноски
FROM (

		SELECT	t.*,
				@N_Sum_For_Split - ISNULL(LAG(t.N_Sum_Step) OVER (ORDER BY t.N_Order,t.ID) ,0) N_Need		-- необходимое количество для разнесения
		FROM (
				SELECT	t.*,
						SUM(t.N_SUM) OVER (ORDER BY N_Order,ID)	N_Sum_Step		-- нарастающий итог
				FROM t
			 )	t
	) t 



Сумма все строк в пределах одного F_DOC не должна превышать N_Sum_Max_By_Doc. Как сделать это, не прибегая к еще одной разноске ? Остаток после разнесения = 0.6 (4.6 - 4) для F_Doc = 1 потребуется для следующих итераций разнесения. На примере - одна итерация разнесения (сумма = 5.2).

В действительности аналог таблицы t будет очень большим и количество документов тоже. Как это сделать , реализовав это с помощью минимального количества разносок / циклов ?
...
Рейтинг: 0 / 0
25.06.2018, 09:37
    #39665073
Kopelly
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение при разноске.
Cristiano_Rivaldo,

@N_Sum_For_Split и N_Sum_Max_By_Doc всегда положительные?
...
Рейтинг: 0 / 0
25.06.2018, 09:38
    #39665074
Cristiano_Rivaldo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение при разноске.
Kopelly,

Да
...
Рейтинг: 0 / 0
25.06.2018, 09:40
    #39665075
Cristiano_Rivaldo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение при разноске.
Подразумевается что отрицательные суммы в t уже пересчитаны и разнесены и теперь там только положительные N_Sum
...
Рейтинг: 0 / 0
25.06.2018, 10:38
    #39665133
Kopelly
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение при разноске.
Код: 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.
DECLARE @N_Sum_For_Split  MONEY = 4.2  -- сумма для разнесения 

;WITH t 
(	ID ,				-- идентификатор (PK)
	N_Order,			-- порядок сортировки (для нарастающего итога)
	N_SUM,				-- сумма 
	F_DOC,				-- идентификатор докуменат (FK)				
	N_Sum_Max_By_Doc	-- максимальная сумма в рамках одного документа, которая должна быть после разноски
) AS
(
	SELECT 1,0,3.5,1,4
	UNION ALL
	SELECT 2,1,1.1,1,4
	UNION ALL
	SELECT 3,2,0.8,2,0.4
),
Ost_Doc as --Ограничиваем суммы по документам согласно N_Sum_Max_By_Doc 
(
Select *,
case When N_Sum_Max_By_Doc - sum(t.N_SUM) over (Partition by F_DOC Order by N_Order, ID) < 0 Then 
          Case When N_Sum_Max_By_Doc - sum(t.N_SUM) over (Partition by F_DOC Order by N_Order, ID) + t.N_Sum > 0 
		       Then N_Sum_Max_By_Doc - sum(t.N_SUM) over (Partition by F_DOC Order by N_Order, ID) + t.N_Sum
			   else 0 End
     else N_SUM End as N_SUM_Ost
From T
),
Ost_all as --Определяем разноски на сумму @N_Sum_For_Split
(
Select *,
case When @N_Sum_For_Split - sum(t.N_SUM_Ost) over (Order by N_Order, ID) < 0 Then 
          Case When @N_Sum_For_Split - sum(t.N_SUM_Ost) over (Order by N_Order, ID) + t.N_SUM_Ost > 0 
		       Then @N_Sum_For_Split - sum(t.N_SUM_Ost) over (Order by N_Order, ID) + t.N_SUM_Ost
			   else 0 End
     else N_SUM_Ost End as N_SUM_Ost_All

From Ost_Doc t
)
Select * From Ost_all
...
Рейтинг: 0 / 0
25.06.2018, 10:46
    #39665139
Cristiano_Rivaldo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение при разноске.
Kopelly, Спасибо большое !
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Ограничение при разноске. / 6 сообщений из 6, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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