2016-05-17 10 views
1

行ごとに更新するが、現在の行を更新した後に各行のコンテキストを再度評価したい。行を行単位で更新する

例:

ID Type  Count Lag  Lead  FirstNotZero Calculate (CASE) 
1 Ad-Aware 438584 438541 438602 438584  438584 
2 Ad-Aware 438602 438584 0   438602  438602 
3 Ad-Aware 0  438602 0   438602  438602 
4 Ad-Aware 0  0  0   438602  438602  
5 Ad-Aware 0  0  0   438602  438602  
6 Ad-Aware 0  0  438746 438602  438602  
7 Ad-Aware 438746 0  438782 438746  438746 
8 Ad-Aware 438782 438746 438806 438782  438782 

は私が計算した値を持つすべての0の値を置き換えたいです。つまり、このロジックで計算する必要があります。

CASE 
WHEN Count = 0 AND Lag != 0 AND Lead != 0 THEN (Lag + Lead)/2 
ELSE FirstNotZero 
END 

だから、ラグとリードのCount = 0 and Lag and Lead values are known、平均が計算されなければならないとき。

私が今必要としたいのは、1行を取得し、計算を評価し、必要に応じて更新し、行ごとに更新することです。

ここでの問題は、ID 6の行です。行5が計算されるとすぐに、行6の遅延が分かります。したがって計算結果は483674 [(438602 + 438746)/ 2]で、現在は438602ではありません。

このような更新を行単位で実行するにはどうすればよいですか?たぶんCURSOR UPDATEと?

+0

はあなたがカーソルを通してそれを試したことがありますか?次の行の計算が前の行の計算値に依存する場合は、Cursorが唯一の選択肢だと私は考えます。 – Lali

+0

6行目は438602 + 438746/2ではなく、438602 + 438782/2であるべきですか? –

+0

あなたは置換値を計算する方法について論理を教えていますが、私が見る限り、あなたの例ではそれを適用できる行はありません。*カウント値が「0」のすべての*行には少なくとも1つ「Lag」または「Lead」も「0」に等しい。 –

答えて

0

あなたは、あなたが最初に持っている場合にはISNULL(lag, 0) + ISNULL(lead, 0)ようlagleadOUTER APPLYといくつかのISNULLチェックを使用したいと思うでしょう次の行数と0でない最初の前の行を知っているとcalculate.Probablyにそれらを使用する必要がありますまたはゼロカウント:

DECLARE @t TABLE (ID INT, Count INT) 
INSERT INTO @t 
VALUES (1, 438584), 
     (2, 438602), 
     (3, 0), 
     (4, 0), 
     (5, 0), 
     (6, 0), 
     (7, 438746), 
     (8, 438782); 


WITH cte1 
      AS (SELECT * 
       FROM  @t t 
         CROSS APPLY (SELECT TOP 1 
               count AS lag 
             FROM  @t 
             WHERE  count <> 0 
               AND id <= t.id 
             ORDER BY id DESC 
            ) ca 
      ), 
     cte2 
      AS (SELECT * , 
         LEAD(lag) OVER (ORDER BY id) AS lead 
       FROM  cte1 
      ) 
    UPDATE cte2 
    SET  count = (lag + lead)/2 
    WHERE count = 0 

SELECT * 
FROM @t 

出力と最後の行:

1 438584 
2 438602 
3 438602 
4 438602 
5 438602 
6 438674 
7 438746 
8 438782 
+0

ありがとう。それは、値が低すぎるので、3-5行を除いて良いでしょう。その数は、最低(行1)から最高(行8)に向かって増加傾向にあるはずです。 – DNac

+0

しかし、行3では '(438602 + 0)/ 2 = 219301'、いいえ? –

+0

したがって、Lead = 0なのでFirstNotZeroに置き換えられます。私の質問の場合を参照してください。 – DNac

関連する問題