私は今日と昨日のかなりの部分を、SQL でループまたはカーソルを使用するかどうかを決定するか、問題を解決するためにセット ベースのロジックを使用する方法を理解することに費やしました。私はロジックを設定するのは初めてではありませんが、この問題は特に複雑に思えます。
問題
アイデアは、すべてのトランザクション (数千、数億) のリストとそれらが発生した日付がある場合、そのデータの一部を日次合計テーブルに結合して、レポートと分析によってより迅速に表示できるようにすることです。システム。このための擬似コードは次のとおりです。
foreach( row in transactions_table )
if( row in totals_table already exists )
update totals_table, add my totals to the totals row
else
insert into totals_table with my row as the base values
delete ( or archive ) row
おわかりのように、ループのブロックは比較的簡単に実装でき、カーソル/ループの反復も同様です。ただし、実行時間は非常に遅くて扱いにくく、私の質問は次のとおりです。そのようなタスクを実行するための非反復的な方法はありますか、それともこれは「吸い上げ」てカーソルを使用する必要があるまれな例外の 1 つですか? ?
このトピックについていくつかの議論がありました。いくつかは似ているように見えますが、if/else ステートメントと別のテーブルでの操作のために使用できません。たとえば、次のようになります。
列ベースのロジックで SQL データの行をマージする方法は? この質問は、すべての合計のビューを返すだけであり、実際には別のテーブルへの追加または更新について論理的な決定を下していないため、適用できないようです
SQL ループには、可能と思われるいくつかのケース ステートメントを使用した選択についていくつかのアイデアがあるようですが、別のテーブルのステータスに応じて実行する必要がある 2 つの操作があるため、このソリューションは適合しないようです。
カーソルを使用せずに各行の SQL ストアド プロシージャを呼び出すグループ。
この苛立たしい問題に取り組むためのアドバイスはありますか?
ノート
SQL Server 2008 を使用しています
スキーマのセットアップは次のとおりです。
合計: (id int pk、totals_date date、store_id int fk、machine_id int fk、total_in、total_out)
トランザクション: (transaction_id int pk、transaction_date datetime、store_id int fk、machine_id int fk、transaction_type (IN または OUT)、transaction_amount decimal)
合計は、店舗別、機械別、および日付別に計算する必要があり、すべての IN トランザクションを total_in に合計し、OUT トランザクションを total_out に合計する必要があります。目標は、疑似データ キューブを動作させることです。