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

Откуда: от верблюда
Сообщений: 408
Бьюсь уже несколько часов, но пока безрезультатно

SQL2016

Есть табличка
rICAOrDaterCodebAmountpAmountbQuantpQuantlagAmountlagQuantRowNumrAmount
uuoo2017-12-311234561000100101010
uuoo2018-01-01123456702007101001020
uuoo2018-01-02123456501005870730
uuoo2018-01-031234565005050540
uuee2017-12-311234561000100101010
uuee2018-01-01123456700701001020
uuee2018-01-021234565005070730


Группировки строятся в разрезе rICAO,rCode
Сортировка внутри группы по rDate

Забегая вперед: Апдейтом это делается без проблем, но сортировку в нем не задашь и последовательность не всегда правильная получается

Нужно в столбец rAmount первой строки установить значение, вычислив его по формуле (пишу формулу как для апдейта)
@rAmount=rAmount=(@lagAmount+pAmount)/(@lagQuant+pQuant)
где
@lagAmount = bAmount = bQuant * @rAmount
@lagQuant = bQuant
после вычисления первой строки запоминаем результат, чтобы использовать его в следующей строке
@rAmount для самой первой строки вычисляется как @rAmount=bAmount/bQuant (разумеется с проверками, во избежание деления на ноль)

Получается такой результат
rICAOrDaterCodebAmountpAmountbQuantpQuantlagAmountlagQuantRowNumrAmount
uuoo2017-12-3112345610001001010110
uuoo2018-01-0112345610520071010010215
uuoo2018-01-0212345668.333333333333310058707313.6666666666667
uuoo2018-01-0312345668.3333333333333050505413.6666666666667
uuee2017-12-31123456136.66666666666701001010113.6666666666667
uuee2018-01-0112345695.666666666666707010010213.6666666666667
uuee2018-01-0212345668.3333333333333050707313.6666666666667


Есть еще вариант с курсором, но что-то он как-то не очень :/

Подскажите, как решаются такие задачи?
29 авг 18, 09:43    [21657161]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать результат вычисления предыдущей строки в текущей строке (не сумма)?  [new]
court
Member

Откуда:
Сообщений: 2021
TJ001
Подскажите, как решаются такие задачи?
рекурсивным СТЕ, например ...
29 авг 18, 09:49    [21657170]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать результат вычисления предыдущей строки в текущей строке (не сумма)?  [new]
aleksrov
Member

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

Обычные оконные функции
29 авг 18, 09:50    [21657173]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать результат вычисления предыдущей строки в текущей строке (не сумма)?  [new]
aleksrov
Member

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

Через оконные, для текущей строки берем значение предыдущей и считаем все что надо, через case можно сделать проверку на первую строку в окне, первое что пришло в голову.
29 авг 18, 09:52    [21657176]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать результат вычисления предыдущей строки в текущей строке (не сумма)?  [new]
TJ001
Member

Откуда: от верблюда
Сообщений: 408
aleksrov,

С оконкой не получается, потому что должна быть примерно такая конструкция
select iif((lagQuant*pQuant)<>0,(lagAmount+pAmount)/(lagQuant+pQuant),lagAmount) abc
, lag(abc) OVER(partition by rCFDid, rcode,rdate order by rdate) abb
from @res


но так не работает
29 авг 18, 10:00    [21657188]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать результат вычисления предыдущей строки в текущей строке (не сумма)?  [new]
TJ001
Member

Откуда: от верблюда
Сообщений: 408
криво написал оконку, конечно, но смысл понятен, я думаю
29 авг 18, 10:07    [21657195]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать результат вычисления предыдущей строки в текущей строке (не сумма)?  [new]
TJ001
Member

Откуда: от верблюда
Сообщений: 408
court,

с рекурсивным cte я пробовал, но что-то тоже какая-то ерунда выходила
может неправильно делал, конечно...
но результат у меня получался такой же, как если делать нарастающий итог оконкой, типа
SUM(a) OVER (PARTITION BY b ORDER BY c ROWS UNBOUNDED PRECEDING) 
29 авг 18, 10:27    [21657233]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать результат вычисления предыдущей строки в текущей строке (не сумма)?  [new]
court
Member

Откуда:
Сообщений: 2021
TJ001
court,

с рекурсивным cte я пробовал, но что-то тоже какая-то ерунда выходила
может неправильно делал, конечно...
но результат у меня получался такой же, как если делать нарастающий итог оконкой, типа
SUM(a) OVER (PARTITION BY b ORDER BY c ROWS UNBOUNDED PRECEDING) 
типа этого, что-то:
;with cte as (
	select 
		*
		,rAmount	=bAmount/bQuant
	from [Есть табличка]
	where RowNum=1

	union all

	select
		a.*
		,rAmount=(b.lagAmount+a.pAmount)/(b.lagQuant+a.pQuant)
	from [Есть табличка] a inner join cte b
		on a.RowNum=b.RowNum+1 and a.rICAO=b.rICAO and a.rCode=b.rCode)

select * from cte
29 авг 18, 11:26    [21657319]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать результат вычисления предыдущей строки в текущей строке (не сумма)?  [new]
TJ001
Member

Откуда: от верблюда
Сообщений: 408
court,

Да, именно такой вариант я и пробовал, но он возвращает не то, что нужно


пока нужный результат дает только курсор или апдейт таблицы, с кластеризованным индексом, чтобы не нарушалась последовательность
29 авг 18, 15:09    [21657763]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать результат вычисления предыдущей строки в текущей строке (не сумма)?  [new]
Владислав Колосов
Member

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

курсор запилите.
29 авг 18, 16:16    [21657858]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать результат вычисления предыдущей строки в текущей строке (не сумма)?  [new]
TJ001
Member

Откуда: от верблюда
Сообщений: 408
Владислав Колосов,

Только и остается :(
29 авг 18, 16:45    [21657891]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить