2016-07-13 2 views
-1

У меня есть таблица в SQL Server 2014 и нужно рекурсивно обновлять столбец на основе его предыдущего значения. Напр.Обновите столбец и верните его в том же запросе

--------------------------------------- 
ID | price | diff_with_prev_price | 
--------------------------------------- 
1 | 29  | 0     | 
2 | 25  | 0     | 
3 | 20  | 0     | 
4 | 35  | 0     | 
5 | 40  | 0     | 
--------------------------------------| 

Я хочу рекурсивно обновлять третий столбец, как показано ниже

--------------------------------------- 
ID | price | diff_with_prev_price | 
--------------------------------------- 
1 | 29  | 0     | 
2 | 25  | 25     | 
3 | 20  | 5     | 
4 | 35  | -30     | 
5 | 40  | 10     | 
--------------------------------------| 

Это суммирования предыдущего значения третьего столбца со следующим значением «цена». Может кто-нибудь, пожалуйста, дайте некоторый намек на это, используя CTE или LEAD/LAG, но не используя курсоры. Мне нужно обновить миллионы строк.

+5

Выходной образец вы предоставили кажется неправильным! Почему первый 1 '0', а второй -' 25'? Почему 'ID = 5' не получил' -70'? Кажется, что логика меняет каждый. – sagi

+0

Вы можете использовать обычное обновление, используя «price = price- (любые расчеты)». – Gnqz

+0

Вы делаете «обратную рекурсивную»? В противном случае вывод не имеет смысла. Кроме того, какую версию SQL-сервера вы используете? Если 2008 или выше, LEAD/LAG будет вашим лучшим выстрелом. – martennis

ответ

0

Вы можете попробовать это:

SELECT 1 AS ID , 29 AS price, 0 AS diff_with_prev_prive 
INTO #tmp 
UNION SELECT 2 AS ID , 25 AS price, 0 AS diff_with_prev_prive 
UNION SELECT 3 AS ID , 20 AS price, 0 AS diff_with_prev_prive 
UNION SELECT 4 AS ID , 35 AS price, 0 AS diff_with_prev_prive 
UNION SELECT 5 AS ID , 40 AS price, 0 AS diff_with_prev_prive 

WITH cte AS 
(
    SELECT 
     ID 
     , price 
     , diff_with_prev_prive 
     , price - ISNULL(LAG(price) OVER (ORDER BY ID),0) AS new_value 
    FROM #tmp 
) 
UPDATE t 
SET diff_with_prev_prive = t.new_value 
FROM cte t 

SELECT * FROM #tmp 
+0

Я изменил значение 1 на 29, но это всего лишь вопрос об установке нулевого значения. – Kilren

+0

Единственная проблема здесь в том, что функции Windowed не разрешены в инструкции обновления. Но использование cte позволяет это сделать. другой вариант - использовать таблицу Temp, но я не вижу смысла специально для выступлений. – Kilren

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