2016-07-13 6 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     | 
--------------------------------------| 

私は、それは「価格」の次の値を持つ3列目の前の値の合計です

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

以下のように再帰的に3番目の列を更新します。 誰かがCTEまたはLEAD/LAGを使用してカーソルを使用せずにこれを行うためのヒントを与えてもらえますか?私は百万行を更新する必要があります。

+5

出力サンプルが間違っているようです!なぜ最初の1は「0」で、2番目のものは「25」ですか?なぜ 'ID = 5'は' -70'を得られませんでしたか?論理がそれぞれ変わるようです。 – sagi

+0

"price = price-(何でも計算)"を使って通常の更新を使うことができます。 – Gnqz

+0

あなたは '逆帰的再帰'をしていますか?それ以外の場合、出力は意味をなさない。また、どのバージョンのSQL Serverを使用していますか? 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

最初の値を29に変更しましたが、それはnull値を設定するだけです。 – Kilren

+0

ここで問題となるのは、Windowed関数はupdate文では使用できないということだけです。 しかし、cteを使うとそうすることができます。 他のオプションは、Tempテーブルを使用することですが、私はパフォーマンスのために特別なポイントが表示されません。 – Kilren

関連する問題