2017-10-23 10 views
0

SQL Serverのテーブルに問題があります。ときどきインサート中に通常の値(20-50-80)が1000000で変更されました。それは本当にまれですが、平均を確保するためには新しい解決策を見つける前に修正する必要があります。SQL Serverのカーソル:ループ/条件を使用して値を検索して置き換えます。

私は、1000000を超える値を取って、それらの間の値の平均で置き換えたいと考えています。

This picture show the problem.

私はSQLでのカーソルで探しています。

ここに私のコードの例があります。その結果に関するいくつかの問題。

CREATE PROCEDURE [dbo].[Avg_Kwh_TagValuesArchive]  
AS 

BEGIN 

DECLARE @tagId INT 
DECLARE @localTime DATE 
DECLARE @tagValue FLOAT 
DECLARE @limit FLOAT 
DECLARE @temp FLOAT 
DECLARE @tagValueBefore FLOAT 
DECLARE @tagValueAfter FLOAT 
SET @limit = 999999.9 

DECLARE Cursor_FalseValues CURSOR 
FOR 
    SELECT TagID, LocalTime, TagValue 
    FROM TagValuesArchive 
    ORDER BY LocalTime DESC 

OPEN Cursor_FalseValues 

FETCH Cursor_FalseValues 
INTO @tagId, @localTime, @tagValue 

WHILE(@@FETCH_STATUS = 0) 
BEGIN 

      IF (@tagValue>[email protected]) 
      BEGIN 

       SET @tagValueBefore = 
       (
        SELECT TOP 1 TagValue 
        FROM TagValuesArchive 
        WHERE LocalTime < @localTime 
        AND TagID = @tagID 
        AND TagValue IS NOT NULL 
        ORDER BY LocalTime DESC 
       ) 

       SET @tagValueAfter = 
       (
        SELECT TOP 1 TagValue 
        FROM TagValuesArchive 
        WHERE LocalTime > @localTime 
        AND TagID = @tagID 
        AND TagValue IS NOT NULL 
        ORDER BY LocalTime DESC 
       ) 

       UPDATE dbo.TagValuesArchive 
       SET TagValue= ((SUM(@tagValueBefore + @tagValueAfter))/2) 
       FROM dbo.TagValuesArchive 
       WHERE LocalTime = @localTime 
       AND TagID = @tagID 

       FETCH NEXT FROM Cursor_FalseValues 
       INTO @tagId, @localTime, @tagValue 

      END 
     ELSE 
      BEGIN 
       -- Fetch of the Cursos increment the line 
       FETCH NEXT FROM Cursor_FalseValues 
       INTO @tagId, @localTime, @tagValue 
      END 
    -- Fetch of the Cursos increment the line 
    --FETCH NEXT FROM Cursor_FalseValues 
    --INTO @tagId, @localTime, @tagValue 
END 

CLOSE Cursor_FalseValues 
DEALLOCATE Cursor_FalseValues 
END 

私の問題はCursorを使用する良い例だと思っていますが、私の頭にはあまり明確ではありません。 間違った値とその間の値を取ることができます。しかし、データベースの更新は機能しません。

私はそれがカーソルの問題か更新かどうか分かりません。たぶんコード構文の問題です。

ありがとうございました。

答えて

0

あなたはこのような何か試すことができます:ここに何が起こる

DECLARE @t TABLE (
    id int, 
    val float 
) 


INSERT INTO @t (id, val) 
VALUES 
(1,.5), 
(2,.7), 
(3,.3), 
(4,.74), 
(5,.2341234), 
(6,10000000), 
(7,.9), 
(8,.8), 
(9,.87123), 
(10,100000000), 
(11,.99) 
SELECT * FROM @t 

DECLARE @limit FLOAT = 1000000; 

;WITH OutOfOBoundsValues AS (
    SELECT id FROM @t WHERE val >= @limit 
), Neighbourvalues AS (
    SELECT O.id, (t1.val+t2.val)/2 newval FROM OutOfOBoundsValues O 
    JOIN @t t1 ON t1.id = O.id-1 
    JOIN @t t2 ON t2.id = O.id+1 

) 
UPDATE @t 
SET val = N.newval 
FROM @t t 
JOIN Neighbourvalues N ON t.id = N.Id 


SELECT * FROM @t 

は、私たちが限界とし、上記と同じデータを選択することです。

次に、隣接する値を取得し、それらの平均値を計算します。

最後に、範囲外の値を平均値で更新します。

これはカーソルよりもはるかに速くなければなりません。

+0

この情報をお寄せいただきありがとうございます。 – Zebiphire

関連する問題