SQLによるレコードの統合処理を行いたいです。
実際に想定通り動くSQLは組めたのですが、重くて使い物になりません。
パフォーマンスの改善方法、もしくは別の案などがあれば教えていただきたいです。
実現したいこと
以下具体例です。
次のようなテーブルAがあったとします。
テーブルA
会社名 | 取引先名 | 取引金額 |
---|---|---|
A社 | hoge社 | 10000 |
A社 | fuga社 | 2000 |
A社 | piyo社 | 3000 |
B社 | hoge社 | 40000 |
B社 | fuga社 | 5000 |
B社 | puyo社 | 6000 |
C社 | hoge社 | 7000 |
C社 | fuga社 | 8000 |
ここでfuga社がhoga社に吸収され、以下のようにテーブルを更新する必要が出てきました。
会社名 | 取引先名 | 取引金額 |
---|---|---|
A社 | hoge社 | 12000 |
A社 | piyo社 | 3000 |
B社 | hoge社 | 45000 |
B社 | puyo社 | 6000 |
C社 | hoge社 | 15000 |
前提として、元のテーブルAの取引先には会社名1つに対して必ずhoge社とfuga社が1つずつ入っています。
発生している問題
目的の処理を実現するために以下のようなSQLを作成しました。
SQL
1DECLARE @CompanyName NVARCHAR(100); 2 3 DECLARE crTriggerList CURSOR 4 FOR 5 SELECT DISTINCT [会社名] AS CompanyName --会社名の一覧 6 FROM [テーブルA] 7 8 OPEN crTriggerList; 9 10 FETCH NEXT FROM crTriggerList 11 INTO @CompanyName; 12 13 WHILE @@FETCH_STATUS = 0 14 BEGIN 15 DECLARE @Price DECIMAL(12,0); 16 17 --統合前の合計 18 SELECT @Price = SUM(取引金額) 19 FROM [テーブルA] 20 WHERE 会社名 = @CompanyName 21 AND (取引先名= 'hoge' 22 OR 取引先名 = 'fuga') 23 24 --統合した計算結果で更新 25 UPDATE テーブルA 26 SET 取引金額 = @Price 27 FROM [テーブルA] 28 WHERE 会社名 = @CompanyName 29 AND 取引先名= 'hoge' 30 31 --吸収された会社削除 32 DELETE FROM [テーブルA] 33 WHERE 会社名 = @CompanyName 34 AND 取引先名= 'fuga' 35 36 FETCH NEXT FROM crTriggerList --会社名ごとに上記の処理を繰り返す 37 INTO @CompanyName; 38 END 39 40 CLOSE crTriggerList; 41 DEALLOCATE crTriggerList; 42
一応これで期待通りの結果は得られるのですが、レコードが増えると時間がかかりすぎてしまいます。
パフォーマンスの改善方法、もしくはカーソル処理を使わない別の案などがあれば教えていただきたいです。
よろしくお願いします。
補足情報(FW/ツールのバージョンなど)
Microsoft SQL Server Management Studio 18
Microsoft SQL Server 2019 (RTM-GDR) (KB4583458) - 15.0.2080.9 (X64) Nov 6 2020 16:50:01 Copyright (C) 2019 Microsoft Corporation Enterprise Edition (64-bit) on Windows Server 2019 Datacenter 10.0 <X64> (Build 17763: ) (Hypervisor)
回答2件
あなたの回答
tips
プレビュー