重要: これを SQL Server 2000 互換にする必要があります。
累積合計が必要ですが、現在の日付フィールドに基づいて、現在使用しているような更新クエリは機能しますが、非常に遅いです (醜い暗黙の RBAR 三角結合):
UPDATE #RPT
SET DailySumAccum =
(SELECT SUM(COALESCE(CTACTE2.Amount,0))
FROM #RPT_CTACTE CTACTE2
WHERE CTACTE2.IsAvailable = #RPT_CTACTE.IsAvailable
AND CTACTE2.CodCustomer = #RPT_CTACTE.CodCustomer
AND CTACTE2.ItemType = #RPT_CTACTE.ItemType
AND CTACTE2.CodItem = #RPT_CTACTE.CodItem
AND EsCtaCorrienteMon = -1
AND DATEDIFF(day, CTACTE2.OrderDate, #RPT_CTACTE.OrderDate) >= 0)
WHERE #RPT_CTACTE.EsSaldoAnterior = 0
AND EsCtaCorrienteMon = -1
合計を実行するためにカーソル メソッドを使用してみましたが、RBAR の問題を修正できません。日付の比較がまだ存在し、それでも非常に遅いことがわかります。
-- this is inside the cursor
IF (@EsCtaCorrienteMon = -1)
BEGIN
SELECT @NetoDiarioAcum = SUM(COALESCE(Amount,0))
FROM #RPT_CTACTE
WHERE IsAvailable = @IsAvailable
AND CodCustomer = @CodCustomer
AND ItemType = @ItemType
AND CodItem = @CodItem
AND EsCtaCorrienteMon = -1
AND DATEDIFF(day, OrderDate, @OrderDate) >= 0
END IF
したがって、この累積合計の問題は、そこでの日付の比較であり、クエリが非常に遅くなっていることです (10 分間実行した後にコードを停止し、この Update カーソルの実行に 3 秒しかかからないことにコメントしました)、私が持っている行数テストされたのは 28K です。レコード数が増えると、所要時間が指数関数的に増加しているように見えます。そのため、ここで RBAR が実行されていることが問題であると想定しています (「Row-By-Agonizing-Row」を意味します)。
編集:いくつかのテストの後、日付だけが問題ではないように見えます.カーソル内の変数を合計するだけで、この実行中の合計を作成する方法はありますか?
EDIT2:現在、最初の更新(4つのフィールドと日付に基づく1日の合計)を作成する方法を探していますが、より速く、カーソル内にロジックを手動で追加することに近づきましたが、カーソル大きくなりすぎて管理が困難になったので、この場合に最適な (より高速な) ランニング トータル手法はどれでしょうか? そして、ここでそのテクニックをどのように実装しますか? これは単純な現在の合計ではありません。これらのフィールドのいずれかが変更された場合はカットする必要があります。フィールドのEsSaldoAnterior
変更は 0 または -1 のみです。このフィールドが 0 の場合、更新は外側のテーブルにのみ影響しますが、このフィールドが -1 の場合でも、内側の現在の合計は合計されます。 EsSaldoAnterior
「以前の金額」のようなものを意味し、実行中の合計がゼロから開始されるべきではないことを意味します。最初にこれらの金額の合計を開始する必要があります (存在する場合)。これは、ORDER BY を使用する場合の順序です。
ORDER BY IsAvailable, CodCustomer, ItemType, CodItem, OrderDate, EsSaldoAnterior