3

SQLで計算された合計を更新しようとしています

基本的に私はテーブルを持っています:

ImportID  SeiralNumber   Day   Hour     value    Difference   Complete
1             123         1     1         6         NULL        0
2             123         1     2         8         NULL        0
3             123         1     5         21        NULL        0
4             123         1     6         28        NULL        0
5             222         2     2         12        NULL        0
6             222         2     5         18        NULL        0
7             222         2     4         16        NULL        0
8             222         1     12        8         NULL        0

各シリアル番号には、1 から 365 までの日と 1 から 12 までの時間があります。私がやりたいのは、前の記録から提出された差を計算することだけです。

したがって、ImportID 6 を取得します。同じ日とその前の時間 (importID 7) にあるレコードを取得する必要があり、18 -17 = 1 である値フィールドを使用して差を更新する必要があります。

注意: シーケンスにギャップがある可能性があり、前のレコードがない場合、差は のままNULLです。それらが計算されたら、違いが現在あり、それがまだテーブルに存在しない場合にのみ、新しいテーブルに挿入する必要があります。挿入が成功すると、それらはcompletenot nullとしてマークされます。また、前のレコードは前日 (1 日 1 時 12 分) の前のレコード (2 日 1 時) になる場合があります。

現在、ループを使用してnull値を選択し、前のレコードを取得し、レコードを更新し、OKであれば他のテーブルに挿入し、Completedフィールドを更新しています。

私の問題は、これが 100 万のレコードで機能しており、該当するレコード (完了 = 0) を選択して一時テーブルに入れ、それぞれをループするのに時間がかかることです。

これらを更新ステートメントとして一括処理するより迅速な方法はありますか? それとも別々の発言?

結果は

ImportID  SeiralNumber   Day   Hour     value    Difference   Complete
1             123         1     1         6         NULL        0
2             123         1     2         8         2           1
3             123         1     5         21        NULL        0
4             123         1     6         28        7           1
5             222         2     1         12        4           1
6             222         2     5         18        2           1
7             222         2     4         16        NULL        0
8             222         1     12        8         NULL        0

前もって感謝します

4

1 に答える 1

3

これが基本だと思いますよね?

DECLARE @TABLE TABLE
(
    ImportId INT,
    SerialNumber INT,
    Day INT,
    Hour INT,
    Value INT,
    Difference INT,
    Complete INT
)

INSERT INTO @TABLE VALUES
(1,123,1,1,6,NULL,0),
(2,123,1,2,8,NULL,0),
(3,123,1,5,21,NULL,0),
(4,123,1,6,28,NULL,0),
(5,222,2,1,12,NULL,0),
(6,222,2,5,18,NULL,0),
(7,222,2,4,16,NULL,0),
(8,222,1,12,8,NULL,0)

SELECT * FROM @Table

UPDATE T
    SET T.Difference = T.Value - TT.Value,
    Complete = 1
FROM
(
    SELECT *
    ,ROW_NUMBER() OVER (PARTITION BY SerialNumber ORDER BY Day ASC, Hour ASC) AS RowCounter
    FROM @TABLE
    WHERE Complete = 0 --Ignore completed ones  
)AS T
INNER JOIN
(
    SELECT *
    ,ROW_NUMBER() OVER (PARTITION BY SerialNumber ORDER BY Day ASC, Hour ASC) AS RowCounter
    FROM @TABLE
)AS TT
ON T.SerialNumber = TT.SerialNumber
WHERE
(
    T.RowCounter = TT.RowCounter + 1
    AND
    T.Day = TT.Day 
    AND
    T.Hour = TT.Hour + 1
)
OR
(
    T.Day = TT.Day + 1 
    AND
    T.Hour = 1
    AND
    TT.Hour = 12
)

SELECT * FROM @TABLE
于 2012-12-07T11:49:04.283 に答える