2016-11-18 5 views
5

У меня есть некоторые данные, которые находятся в таблице, которую я могу легко выбрать, и мне нужно вычислить выходное значение для каждой строки на основе значения предыдущей строки, за исключением первой строки, которая вычисляется с использованием значения, которое я сначала рассчитываю в запросе выбора. Я пробовал несколько итераций рекурсивного кода и использовал CTE, но мне не удалось заставить его работать. Я заставляю себя сумасшедшим, пытаясь заставить его работать, и я бы предпочел не запускать цикл, потому что он длится долго. Мы работаем SQL Server 2012, и я пишу код в SSMS 2014.Рекурсивный запрос SQL-Server

select 1 as rn, 1.5 x1, 2.5 x2, 2.0 x3, 45 y1, 42 y2, 43 ild into #x 
union all 
select 2 as rn, 1.7 x1, 2.2 x2, 2.1 x3, 55 y1, 12 y2, 43 ild 

код до вычисления первой строки

select x1*y1 + x2*y2 + x3 * ild from #x where rn = 1 

кода для вычисления второго ряда по п строке

select x1*y1 + x2*y2 + x3 * (previous row's calculated value) 

, пожалуйста, дайте мне знать, если что-то у меня отсутствует, потому что у меня есть 8760 строк данных, которые мне нужно прокручивать 57 раз (каждый из них - другой набор данных), и выполнение цикла не является быстрым enoug h для чего мне это нужно.

+2

Использовать LAG/LEAD? Это может быть проще, чем рекурсивный cte. – dfundako

+0

Если я использую задержку, не вызвало бы у меня 8759 вложенных вычислений к концу запроса? Значение, строка 2 зависит от вычисленного результата строки 1, строка 3 зависит от вычисленного результата строки 2, которая зависит от вычисленного результата строки 1. Так что строка 3 будет выглядеть примерно как 'code' select x1 * y1 + x2 * y2 + x3 * (x1 * y1 + x2 * y2 + x3 * (x1 * y1 + x2 * y2 + x3 * ild)) 'code' где значения x внутри первой круглой скобки принадлежат строке он был рассчитан из –

+0

Процедура с курсором и циклом for, вероятно, является хорошим методом для такого каскадного вычисления. – LukStorms

ответ

4

Вот рекурсивное ОТВ, но я не могу говорить с выполнением 87000 строк

;with cte as (
    Select rn ,Calc = cast(x1*y1 + x2*y2 + x3 * ild as money) from #x Where rn=1 
    Union All 
    Select r.rn,cast(r.x1*r.y1 + r.x2*r.y2 + r.x3 * p.Calc as money) 
    From #x r 
    Join cte p on r.rn=p.rn+1 
) 
Select * from cte 
Option (MAXRECURSION 0) 

Возвращает

rn Calc 
1 258.50 
2 662.75 

Я должен отметить: я предполагаю, что RN является дискретно с нет пробелов

+0

thank вы. я попробую и отправлю отчет. –

+0

lol, отправил почти тот же ответ, не получил тост, как обычно, когда есть еще один ответ. удалил мой. – randcd

+0

Функции окон, LAG, LEAD и т. Д. Обычно намного быстрее, чем CTE, потому что сервер их понимает и может их оптимизировать. –

Смежные вопросы