Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Обновление остатков в таблице  [new]
max aka max
Member

Откуда:
Сообщений: 204
Доброго дня всем !

Есть таблица движения товаров:

row_id int,
pos_data datetime
tovar bigint
region bigint
nakl_type varchar(10) -> (приход, расход)
kol_pr decimal(10,2)
price_clean money

row_id - начинается с 1 при каждом изменение товара или региона (ROW_NUMBER() OVER(PARTITION BY tovar, region ORDER BY pos_data) as row_id ),

Нужно в каждой строке данной таблицы получить остаток из предыдущей строки где region и товар Одинаковый, т.е. получается row_id текущей записи должно быть ровно на row_id+1, и полученному остатки прибавить/убавить кол-во из текущей операции и посчитать актуальный остаток по итогам операции.
Сейчас делаю через курсор, но времени очеееееень много уходит, полтора часа на пересчет 150.000 записей.

Подскажите пожалуйста как можно ускорить процесс ? получится ли через CTE ? Курсор был выбран изза того что в каждой операции исходя из типа операции нужно сперва пересчитать цену товара для операции (чтобы товар расходовался по актуальной цене на тот момент) и лишь потом считается конечная актуальная цена.

Спасибо.
2 июл 15, 11:54    [17842359]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
Glory
Member

Откуда:
Сообщений: 104760
max aka max
Сейчас делаю через курсор, но времени очеееееень много уходит, полтора часа на пересчет 150.000 записей.

Да ладно, 1.5 часа только на получение нарастающей суммы ?
2 июл 15, 11:59    [17842414]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
max aka max
Member

Откуда:
Сообщений: 204
Glory
max aka max
Сейчас делаю через курсор, но времени очеееееень много уходит, полтора часа на пересчет 150.000 записей.

Да ладно, 1.5 часа только на получение нарастающей суммы ?


я получаю все движения в темп таблицу, потом прохожу по каждой записи курсором, делаю пересчет актуальной цены и обновляю эту запись в темп таблице.
+

			print 'Начинаем пересчет каждой строки';
			DECLARE ac CURSOR FOR SELECT	row_id, 
											nakl_id ,
											pos_id,
											pos_data,
											nakl_type,
											region,
											tovar,
											kol_pr,
											price_pr,
											nas_stav,
											reg_quan,
											reg_price,
											reg_price_nas,
											old_pos_id
											
			FROM @opers ORDER BY pos_data, nakl_type

			OPEN ac
				FETCH NEXT FROM ac INTO		@_row_id, 
											@_nakl_id ,
											@_pos_id,
											@_pos_data,
											@_nakl_type,
											@_region,
											@_tovar,
											@_kol_pr,
											@_price_pr,
											@_nas_stav,
											@_reg_quan,
											@_reg_price,
											@_reg_price_nas,
											@_old_pos_id
				WHILE @@FETCH_STATUS=0
				BEGIN
						IF @_row_id =1 BEGIN
							/*
							SELECT  @region_quantity = act_quantity,
									@price_clean = act_price,
									@price_clean = act_price_nas
							FROM	getActualPrice
							(
									@_pos_data,
									@_region,
									@_tovar
							);		
							*/
								SET @region_quantity	= @_reg_quan ;
								SET	@price_clean		= @_reg_price ;
								SET	@price_clean		= @_reg_price_nas;
						END ELSE BEGIN 							
							SELECT	@region_quantity	= isnull(reg_quan,			0),
									@price_clean		= isnull(reg_price,			0),
									@price_nas			= isnull(reg_price_nas,		0)
							FROM	@opers
							WHERE	region=@_region AND tovar=@_tovar AND row_id = @_row_id-1;
						END;
						
						IF @_nakl_type='zprixod_prm' AND EXISTS(SELECT reg_price FROM @opers WHERE pos_id=@_pos_id AND @_nakl_type='orasxod_prm')
						BEGIN
							SELECT @_price_pr = reg_price FROM @opers WHERE pos_id=@_pos_id AND @_nakl_type='orasxod_prm';
						END
						
						IF @_old_pos_id>0
						BEGIN
							SELECT @_price_pr = reg_price FROM @opers WHERE pos_id=@_old_pos_id;
							UPDATE @opers SET price_pr = @_price_pr WHERE pos_id=@_pos_id;
						END

						IF @_nakl_type='prixod' OR @_nakl_type='prixod_i' BEGIN
								IF @_price_pr=0 
								BEGIN
									IF @region_quantity + @_kol_pr>0
									BEGIN
										SET @region_quantity	= @region_quantity + @_kol_pr;
										IF @_nakl_type='prixod_i'
										BEGIN 
											UPDATE @opers
											SET		price_pr		=	@price_clean,
													reg_quan		=	@region_quantity, 
													reg_price		=	@price_clean, 
													reg_price_nas	=	@price_nas 
											WHERE pos_id=@_pos_id;
										END ELSE IF @_nakl_type='prixod' BEGIN
											UPDATE @opers
											SET     reg_quan		=	@region_quantity, 
													reg_price		=	@price_clean, 
													reg_price_nas	=	@price_nas 
											WHERE pos_id=@_pos_id;
										END
									END ELSE BEGIN 
										SET @region_quantity		=	@region_quantity + @_kol_pr;
										IF @_nakl_type='prixod_i'
										BEGIN 
											UPDATE @opers
											SET		price_pr		=	@price_clean,
													reg_quan		=	@region_quantity, 
													reg_price		=	@price_clean, 
													reg_price_nas	=	@price_nas 
											WHERE pos_id=@_pos_id;
										END ELSE IF @_nakl_type='prixod' BEGIN
											UPDATE @opers
											SET     reg_quan		=	@region_quantity, 
													reg_price		=	@price_clean, 
													reg_price_nas	=	@price_nas 
											WHERE pos_id=@_pos_id;
										END
									END
								END
								ELSE
								BEGIN

									IF @region_quantity+@_kol_pr>0
									BEGIN
										SET @price_clean = ( @region_quantity * @price_clean + @_kol_pr*@_price_pr ) / ( @region_quantity + @_kol_pr );
										SET @price_nas = @price_clean + (@price_clean*@_nas_stav)/100;
										SET @region_quantity = @region_quantity + @_kol_pr;
									END ELSE BEGIN
										SET @price_clean = @_price_pr;
										SET @price_nas = @price_clean + ( @price_clean * @_nas_stav ) / 100;
										SET @region_quantity = @region_quantity + @_kol_pr;
									END

									UPDATE @opers
									SET		reg_quan		=	@region_quantity, 
											reg_price		=	@price_clean, 
											reg_price_nas	=	@price_nas 
									WHERE pos_id=@_pos_id;

								END
						END
						ELSE IF @_nakl_type='rasxod' OR  @_nakl_type='orasxod_prm' BEGIN
														
								IF @_price_pr > 0
								BEGIN
									IF @region_quantity - @_kol_pr > 0
									BEGIN
										SET @price_clean		=	( @region_quantity * @price_clean - @_kol_pr * @_price_pr ) / ( @region_quantity - @_kol_pr ) ;
										SET @price_nas			=	( @region_quantity * @price_nas   - @_kol_pr * ( @_price_pr + (@_price_pr*@_nas_stav) /100  ) ) / ( @region_quantity - @_kol_pr ) ;
										SET @region_quantity	=	  @region_quantity - @_kol_pr ;
									END 
									ELSE BEGIN
										SET @region_quantity = @region_quantity - @_kol_pr;
									END
								END
								ELSE
								BEGIN
									IF @region_quantity - @_kol_pr > 0
									BEGIN
										SET @price_clean		=	( @region_quantity * @price_clean - @_kol_pr * @price_clean ) / ( @region_quantity - @_kol_pr ) ;
										SET @price_nas			=	( @region_quantity * @price_nas   - @_kol_pr * @price_nas   ) / ( @region_quantity - @_kol_pr ) ;
										SET @region_quantity	=	  @region_quantity - @_kol_pr ;
									END 
									ELSE BEGIN
										SET @region_quantity = @region_quantity - @_kol_pr;
									END
								END

								IF  @_nakl_type='orasxod_prm' 
								BEGIN
									UPDATE @opers 

									SET		reg_quan		=	@region_quantity, 
											reg_price		=	@price_clean, 
											reg_price_nas	=	@price_nas
									WHERE pos_id=@_pos_id AND ( nakl_type='orasxod_prm' );
								END
								ELSE
								BEGIN
									UPDATE @opers 
									SET		reg_quan		=	@region_quantity, 
											reg_price		=	@price_clean, 
											reg_price_nas	=	@price_nas 
									WHERE pos_id=@_pos_id AND nakl_type='rasxod';
								END
																													
						END ELSE IF @_nakl_type='zprixod_prm' BEGIN
							
								IF  @region_quantity + @_kol_pr>0
								BEGIN
									SET @price_clean = ( @region_quantity * @_price_pr + @_kol_pr * @_price_pr) / ( @region_quantity + @_kol_pr );
									SET @price_nas = @price_clean + ( @price_clean * @_nas_stav ) / 100;
									SET @region_quantity = @region_quantity + @_kol_pr;
								END ELSE BEGIN 
									SET @price_clean = @_price_pr;
									SET @price_nas = @price_clean + ( @price_clean * @_nas_stav ) / 100;
									SET @region_quantity = @region_quantity + @_kol_pr;
								END

								UPDATE @opers
								SET		reg_quan  = @region_quantity, 
										reg_price = @price_clean, 
										reg_price_nas=@price_nas 
								WHERE pos_id=@_pos_id AND nakl_type='zprixod_prm';
						END 

				FETCH NEXT FROM ac INTO		@_row_id, 
											@_nakl_id ,
											@_pos_id,
											@_pos_data,
											@_nakl_type,
											@_region,
											@_tovar,
											@_kol_pr,
											@_price_pr,
											@_nas_stav,
											@_reg_quan,
											@_reg_price,
											@_reg_price_nas,
											@_old_pos_id
				END
			CLOSE ac
			DEALLOCATE ac



Сообщение было отредактировано: 2 июл 15, 13:16
2 июл 15, 12:02    [17842445]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
Glory
Member

Откуда:
Сообщений: 104760
max aka max
я получаю все движения в темп таблицу, потом прохожу по каждой записи курсором, делаю пересчет актуальной цены и обновляю эту запись в темп таблице.

И какая команда из вашей прстяни берет 1.5 часа ?
2 июл 15, 12:09    [17842505]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
max aka max
Member

Откуда:
Сообщений: 204
Glory
max aka max
я получаю все движения в темп таблицу, потом прохожу по каждой записи курсором, делаю пересчет актуальной цены и обновляю эту запись в темп таблице.

И какая команда из вашей прстяни берет 1.5 часа ?


Подозреваю что больше времени берет то что я в каждой записи беру последний остаток запросом:
SELECT	@region_quantity	= isnull(reg_quan,			0),
                @price_clean		= isnull(reg_price,			0),
		@price_nas			= isnull(reg_price_nas,		0)
FROM	        @opers
WHERE	region=@_region AND tovar=@_tovar AND row_id = @_row_id-1;
2 июл 15, 12:13    [17842534]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
churupaha
Member

Откуда: Краснодар
Сообщений: 1015
max aka max,

вы бы cte с данными кинули сюда. и что на данном наборе надо получить.
2 июл 15, 12:15    [17842550]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
max aka max
Member

Откуда:
Сообщений: 204
churupaha
max aka max,

вы бы cte с данными кинули сюда. и что на данном наборе надо получить.


я не использую CTE в этом коде, не думал что с CTE получится
2 июл 15, 12:17    [17842561]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
londinium
Member

Откуда: Киев
Сообщений: 1176
автор
я не использую CTE в этом коде, не думал что с CTE получится

Вас немножко другое просят: оформите пример исходных данных в виде
WITH CTE AS
(
  SELECT 1 AS TOVAR_ID,20.98 AS PRICE UNION ALL
  SELECT 2 AS TOVAR_ID,20.00 AS PRICE UNION ALL..... 
)

и желаемый результат
2 июл 15, 12:20    [17842581]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
max aka max
Member

Откуда:
Сообщений: 204
londinium,
Входные данные
WITH CTE AS
(
select 1 as tovar, 1 as region, '2015-01-01' as data, 'prixod' as tip, 1 as kol, 1000 as price, 0 as act_kol UNION ALL
select 1 as tovar, 1 as region, '2015-01-02' as data, 'prixod' as tip, 1 as kol, 900 as price, 0 as act_kol UNION ALL
select 1 as tovar, 3 as region, '2015-01-03' as data, 'prixod' as tip, 1 as kol, 1500 as price, 0 as act_kol UNION ALL
select 2 as tovar, 1 as region, '2015-01-01' as data, 'prixod' as tip, 1 as kol, 1000 as price, 0 as act_kol UNION ALL
select 2 as tovar, 3 as region, '2015-01-05' as data, 'prixod' as tip, 1 as kol, 1100 as price, 0 as act_kol UNION ALL
select 1 as tovar, 1 as region, '2015-01-02' as data, 'rasxod' as tip, 1 as kol, 0 as price, 0 as act_kol UNION ALL
select 1 as tovar, 2 as region, '2015-01-03' as data, 'rasxod' as tip, 1 as kol, 0 as price, 0 as act_kol UNION ALL
select 2 as tovar, 3 as region, '2015-01-06' as data, 'rasxod' as tip, 1 as kol, 0 as price, 0 as act_kol UNION ALL
select 3 as tovar, 1 as region, '2015-01-01' as data, 'prixod' as tip, 1 as kol, 1200 as price, 0 as act_kol UNION ALL
)

Нужен результат: (Поле цены я сам потом буду пересчитать по логике компании, решил убрать чтобы Вам голову не морочить им)

К сообщению приложен файл. Размер - 18Kb
2 июл 15, 12:51    [17842778]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
max aka max
Member

Откуда:
Сообщений: 204
max aka max
londinium,
Входные данные
WITH CTE AS
(
select 1 as tovar, 1 as region, '2015-01-01' as data, 'prixod' as tip, 1 as kol, 1000 as price, 0 as act_kol UNION ALL
select 1 as tovar, 1 as region, '2015-01-02' as data, 'prixod' as tip, 1 as kol, 900 as price, 0 as act_kol UNION ALL
select 1 as tovar, 3 as region, '2015-01-03' as data, 'prixod' as tip, 1 as kol, 1500 as price, 0 as act_kol UNION ALL
select 2 as tovar, 1 as region, '2015-01-01' as data, 'prixod' as tip, 1 as kol, 1000 as price, 0 as act_kol UNION ALL
select 2 as tovar, 3 as region, '2015-01-05' as data, 'prixod' as tip, 1 as kol, 1100 as price, 0 as act_kol UNION ALL
select 1 as tovar, 1 as region, '2015-01-02' as data, 'rasxod' as tip, 1 as kol, 0 as price, 0 as act_kol UNION ALL
select 1 as tovar, 2 as region, '2015-01-03' as data, 'rasxod' as tip, 1 as kol, 0 as price, 0 as act_kol UNION ALL
select 2 as tovar, 3 as region, '2015-01-06' as data, 'rasxod' as tip, 1 as kol, 0 as price, 0 as act_kol UNION ALL
select 3 as tovar, 1 as region, '2015-01-01' as data, 'prixod' as tip, 1 as kol, 1200 as price, 0 as act_kol UNION ALL
)

Нужен результат: (Поле цены я сам потом буду пересчитать по логике компании, решил убрать чтобы Вам голову не морочить им)


Нужно посчитать актуальный остаток после каждой операции в регионе по товару.
2 июл 15, 12:52    [17842784]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
sergeimv
Member

Откуда: Россия, г.Казань
Сообщений: 42
Для наглядности немного изменил таблицу, где overSum (приход/расход), outSum сумма после проведения операции.

if object_id('tempdb..#t') is not null drop table #t
create table #t(
	pos_data datetime, 
	tovar bigint,
	region bigint, 
	overSum decimal(31, 2), 
	outSum decimal(31, 2))

insert into #t
values
	('20150101', 1, 1, 20.00, 0.00),
	('20150102', 1, 1, -5.00, 0.00),
	('20150103', 1, 1, 1.00, 0.00),
	('20150204', 1, 2, 50.00, 0.00),
	('20150205', 1, 2, 110.00, 0.00),
	('20150206', 2, 1, 210.00, 0.00),
	('20150307', 2, 1, -80.00, 0.00),
	('20150308', 3, 1, 10.00, 0.00)

create index ix_#t on #t(pos_data, tovar, region) -- Создадим индекс, что бы update шел в нужной последовательности.

declare @tovar bigint;
declare @region bigint;
declare @outSum int = 0;

update t 
set	
	@outSum = iif(
		@tovar != t.tovar or @tovar = t.tovar and @region != t.region,
		t.overSum, 
		@outSum + t.overSum),
	@tovar = t.tovar,
	@region = t.region,
	t.outSum = @outSum
from
	#t t
with(index(ix_#t)) -- Используем индекс, что бы update шел в нужной последовательности

select * from #t
2 июл 15, 13:10    [17842956]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
sergeimv
Member

Откуда: Россия, г.Казань
Сообщений: 42
И такой update пройдет очень-очень быстро.
2 июл 15, 13:12    [17842975]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
sergeimv
Member

Откуда: Россия, г.Казань
Сообщений: 42
Если нужен нарастающий итог в разрезе товар/регион/дата, то нужно создать индекс таким:
SRC]
create index ix_#t on #t(tovar, region, pos_data)
[/SRC]
2 июл 15, 13:16    [17843008]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
max aka max
Member

Откуда:
Сообщений: 204
sergeimv
Если нужен нарастающий итог в разрезе товар/регион/дата, то нужно создать индекс таким:
SRC]
create index ix_#t on #t(tovar, region, pos_data)
[/SRC]


я раньше тоже делал чтобы последний акт.остаток сохранился в переменном, но тут сортировка не касается ни региона и ни товара, нужно идти исключительно по дате и типу операции, но остаток мы должны взять последний актуальный где товар и регион равны товару и региону текущей записи.
2 июл 15, 13:29    [17843141]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
max aka max
Member

Откуда:
Сообщений: 204
max aka max,

есть ли выход через CTE ?
2 июл 15, 13:56    [17843397]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
churupaha
Member

Откуда: Краснодар
Сообщений: 1015
max aka max,

раз версия сервера не известна...

-- create index idx__data__region__tovar__data__tip on data(region, tovar, data, tip) include(kol, ...);

with data as
(
 select 1 as tovar, 1 as region, '2015-01-01' as data, 'prixod' as tip, 1 as kol, 1000 as price, 0 as act_kol UNION ALL
 select 1 as tovar, 1 as region, '2015-01-02' as data, 'prixod' as tip, 1 as kol, 900 as price, 0 as act_kol UNION ALL
 select 1 as tovar, 3 as region, '2015-01-03' as data, 'prixod' as tip, 1 as kol, 1500 as price, 0 as act_kol UNION ALL
 select 2 as tovar, 1 as region, '2015-01-01' as data, 'prixod' as tip, 1 as kol, 1000 as price, 0 as act_kol UNION ALL
 select 2 as tovar, 3 as region, '2015-01-05' as data, 'prixod' as tip, 1 as kol, 1100 as price, 0 as act_kol UNION ALL
 select 1 as tovar, 1 as region, '2015-01-02' as data, 'rasxod' as tip, 1 as kol, 0 as price, 0 as act_kol UNION ALL
 select 1 as tovar, 1 as region, '2015-01-03' as data, 'rasxod' as tip, 1 as kol, 0 as price, 0 as act_kol UNION ALL
 select 2 as tovar, 3 as region, '2015-01-06' as data, 'rasxod' as tip, 1 as kol, 0 as price, 0 as act_kol UNION ALL
 select 3 as tovar, 1 as region, '2015-01-01' as data, 'prixod' as tip, 1 as kol, 1200 as price, 0 as act_kol
)
select 
	*,
	sum(iif(tip = 'rasxod', -1, 1) * kol) over(partition by region, tovar order by data, tip rows between unbounded preceding and current row) act_kol
from 
	data



tovar region data tip kol price act_kol act_kol
----------- ----------- ---------- ------ ----------- ----------- ----------- -----------
1 1 2015-01-01 prixod 1 1000 0 1
1 1 2015-01-02 prixod 1 900 0 2
1 1 2015-01-02 rasxod 1 0 0 1
1 1 2015-01-03 rasxod 1 0 0 0
2 1 2015-01-01 prixod 1 1000 0 1
3 1 2015-01-01 prixod 1 1200 0 1
1 3 2015-01-03 prixod 1 1500 0 1
2 3 2015-01-05 prixod 1 1100 0 1
2 3 2015-01-06 rasxod 1 0 0 0

похоже?
2 июл 15, 13:58    [17843407]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
max aka max
Member

Откуда:
Сообщений: 204
churupaha
max aka max,

раз версия сервера не известна...

-- create index idx__data__region__tovar__data__tip on data(region, tovar, data, tip) include(kol, ...);

with data as
(
 select 1 as tovar, 1 as region, '2015-01-01' as data, 'prixod' as tip, 1 as kol, 1000 as price, 0 as act_kol UNION ALL
 select 1 as tovar, 1 as region, '2015-01-02' as data, 'prixod' as tip, 1 as kol, 900 as price, 0 as act_kol UNION ALL
 select 1 as tovar, 3 as region, '2015-01-03' as data, 'prixod' as tip, 1 as kol, 1500 as price, 0 as act_kol UNION ALL
 select 2 as tovar, 1 as region, '2015-01-01' as data, 'prixod' as tip, 1 as kol, 1000 as price, 0 as act_kol UNION ALL
 select 2 as tovar, 3 as region, '2015-01-05' as data, 'prixod' as tip, 1 as kol, 1100 as price, 0 as act_kol UNION ALL
 select 1 as tovar, 1 as region, '2015-01-02' as data, 'rasxod' as tip, 1 as kol, 0 as price, 0 as act_kol UNION ALL
 select 1 as tovar, 1 as region, '2015-01-03' as data, 'rasxod' as tip, 1 as kol, 0 as price, 0 as act_kol UNION ALL
 select 2 as tovar, 3 as region, '2015-01-06' as data, 'rasxod' as tip, 1 as kol, 0 as price, 0 as act_kol UNION ALL
 select 3 as tovar, 1 as region, '2015-01-01' as data, 'prixod' as tip, 1 as kol, 1200 as price, 0 as act_kol
)
select 
	*,
	sum(iif(tip = 'rasxod', -1, 1) * kol) over(partition by region, tovar order by data, tip rows between unbounded preceding and current row) act_kol
from 
	data



tovar region data tip kol price act_kol act_kol
----------- ----------- ---------- ------ ----------- ----------- ----------- -----------
1 1 2015-01-01 prixod 1 1000 0 1
1 1 2015-01-02 prixod 1 900 0 2
1 1 2015-01-02 rasxod 1 0 0 1
1 1 2015-01-03 rasxod 1 0 0 0
2 1 2015-01-01 prixod 1 1000 0 1
3 1 2015-01-01 prixod 1 1200 0 1
1 3 2015-01-03 prixod 1 1500 0 1
2 3 2015-01-05 prixod 1 1100 0 1
2 3 2015-01-06 rasxod 1 0 0 0

похоже?

Да, только вот как мне об этом почитать чтобы сделать его для моих данных ?
2 июл 15, 14:04    [17843469]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
churupaha
Member

Откуда: Краснодар
Сообщений: 1015
max aka max,

over()
sum over()

но лучше погугли амазон и качни книжку по window функциям где все потихоничку разжевывается.
2 июл 15, 14:09    [17843511]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
max aka max
Member

Откуда:
Сообщений: 204
churupaha
max aka max,

over()
sum over()

но лучше погугли амазон и качни книжку по window функциям где все потихоничку разжевывается.


мы можем поговорить в скайпе если есть время и возможность ?
дело в том что у тебя в примере данные сортируются по товар, регион и дате, а мне нужно чтобы сортировка шла исключительно по ДАТЕ и ТИПУ, так как может быть что товар в регион 1 пришел из региона 2, и наоборот, в этих записях мне нужно получить вычисленную цену из той же позиции откуда товар пришел.
2 июл 15, 14:15    [17843567]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
sergeimv
Member

Откуда: Россия, г.Казань
Сообщений: 42
max aka max,
Сформулируйте, пожалуйста, нормально условие задачи. И с примерами, что ожидаете получить. А то мы долго гадать можем, что в итоге вам нужно.

Тип операции это всего лишь +/- (Приход/Расход) -
iif(tip = 'prixod', 1, -1)
. Так ведь? Так зачем нам идти по типу операции? Просто можно вставить эту конструкцию iif(tip = 'prixod', 1, -1).

update t 
set	
	@outSum = iif(
		@tovar != t.tovar or @tovar = t.tovar and @region != t.region,
		iif(tip = 'prixod', 1, -1) * t.overSum, 
		@outSum + iif(tip = 'prixod', 1, -1) * t.overSum),
	@tovar = t.tovar,
	@region = t.region,
	t.outSum = @outSum
from
	#t t
with(index(ix_#t)) -- Используем индекс, что бы update шел в нужной последовательности


Т.е. в разрезе tovar - region, мы по возрастанию даты считаем нарастающий итог. Вам же это нужно???
2 июл 15, 14:37    [17843759]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
max aka max
Member

Откуда:
Сообщений: 204
sergeimv
max aka max,
Сформулируйте, пожалуйста, нормально условие задачи. И с примерами, что ожидаете получить. А то мы долго гадать можем, что в итоге вам нужно.

Т.е. в разрезе tovar - region, мы по возрастанию даты считаем нарастающий итог. Вам же это нужно???


если считать только кол-во, то норм, но есть и цена, приход может быть осуществлен из другого региона, в этом случае цена прихода должна взяться из расходной операции того региона ( а цена расхода в той операции может быть еще не рассчитан по Вашей сортировки)
2 июл 15, 14:52    [17843867]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
sergeimv
Member

Откуда: Россия, г.Казань
Сообщений: 42
max aka max
sergeimv
max aka max,
Сформулируйте, пожалуйста, нормально условие задачи. И с примерами, что ожидаете получить. А то мы долго гадать можем, что в итоге вам нужно.

Т.е. в разрезе tovar - region, мы по возрастанию даты считаем нарастающий итог. Вам же это нужно???


если считать только кол-во, то норм, но есть и цена, приход может быть осуществлен из другого региона, в этом случае цена прихода должна взяться из расходной операции того региона ( а цена расхода в той операции может быть еще не рассчитан по Вашей сортировки)


"Нарисуйте" этот пример. На словах не понятен этот переход.
2 июл 15, 15:02    [17843944]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
max aka max
Member

Откуда:
Сообщений: 204
[quot sergeimv]
max aka max
пропущено...
"Нарисуйте" этот пример. На словах не понятен этот переход.


Минуточку нарисую схему
2 июл 15, 15:07    [17843969]     Ответить | Цитировать Сообщить модератору
 Re: Обновление остатков в таблице  [new]
max aka max
Member

Откуда:
Сообщений: 204
sergeimv,

https://www.sql.ru/forum/1164207-a/obnovlenie-ostatkov-i-cen-v-odnoy-tablice-rekursiya создал новую тему , посмотрите пожалуйста, суть задачи так понятна ? буду рад если поможете.
2 июл 15, 15:48    [17844244]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить