2
重複した項目のリストが長い表があります。私はそれらをすべて1つのレコードに統合するためのストアドプロシージャに取り組んでいます。重複した項目のそれぞれには、削除するか、結果のレコードを指すようにキーを変更する必要があるいくつかの子表があります。私のテーブルにはIDがありますが、ReadableIdentifierは重複排除に必要な列です。重複する行と依存関係をカーソルなしで削除する
Id | ReadableIdentifier | Name | UpdatedOn
1 | ABC1234 | Product X | 2014-04-25 16:00:08.000
2 | ABC1234 | Product X | 2014-04-28 16:00:08.000
3 | ABC1234 | Product X | 2014-04-21 16:00:08.000
4 | ABDD9945 | Widget R | 2014-04-25 16:00:08.000
5 | ABDD9945 | Widget R | 2014-04-25 18:45:08.000
ご覧のとおり、レコード1〜3は異なるIDと更新日の重複したものです。 4-5と同じです。私はこれらを1つのレコードに統合し、最新のUpdatedOn日付を持つレコードを優先する必要があります。
最終目標(子テーブルを表示されない):
Id | ReadableIdentifier | Name | UpdatedOn
2 | ABC1234 | Product X | 2014-04-28 16:00:08.000
5 | ABDD9945 | Widget R | 2014-04-25 18:45:08.000
私はこれを行うにはCURSOR
を使用していますが、よりよい解決策がある場合は疑問に思って。
DECLARE dupeCursor CURSOR
FAST_FORWARD
FOR
WITH Counts AS (
SELECT
COUNT(1) Count,
ReadableIdentifier
FROM dbo.Item WITH (NOLOCK)
WHERE ReadableIdentifier IS NOT NULL
GROUP BY ReadableIdentifier)
SELECT
Counts.Count,
Counts.ReadableIdentifier,
Counts.CompanyId
FROM
Counts
WHERE Counts.Count > 1;
OPEN dupeCursor;
DECLARE @readableId VARCHAR(50);
DECLARE @itemToPersistId INT, @itemToDeleteId INT;
FETCH NEXT FROM dupeCursor INTO @readableId;
WHILE @@FETCH_STATUS = 0
BEGIN
WITH V AS (
SELECT Id, ROW_NUMBER() OVER (PARTITION BY ReadableId ORDER BY UpdatedOn DESC) as Row
FROM dbo.Item WITH (NOLOCK) WHERE ReadableId = @readableId
)
SELECT @itemToPersistId = Id
FROM V
WHERE V.Row = 1
CREATE TABLE #itemsToDelete (Id UNIQUEIDENTIFIER)
INSERT INTO #itemsToDelete
SELECT Id
FROM dbo.Item WITH (NOLOCK)
WHERE ReadableId = @readableId AND Id != @itemToPersistId;
--UPDATE CHILDREN TABLES
DELETE FROM dbo.ItemDetails WHERE ItemId IN (SELECT Id FROM #itemsToDelete);
UPDATE dbo.ItemPurchases SET ItemId = @itemToPersistId
WHERE ItemId IN (SELECT Id FROM #itemsToDelete);
UPDATE dbo.PurchaseOrders SET ItemId = @itemToPersistId
WHERE ItemId IN (SELECT Id FROM #itemsToDelete);
DELETE FROM dbo.ItemMetadata WHERE ItemId IN (SELECT Id FROM #itemsToDelete);
--delete Duplicated Items
DELETE FROM dbo.Item WHERE Id IN (SELECT Id FROM #itemsToDelete);
DROP TABLE #itemsToDelete
FETCH NEXT FROM dupeCursor INTO @readableId;
END
CLOSE dupeCursor;
DEALLOCATE dupeCursor;
私はカーソルが最も可能性の高い問題であると認識、しかし、私は1つを使用せずに子テーブルのすべての更新については移動するかどうかはわかりません。
右、私はこれはすでに行っています。 CURSORを使わずに子テーブルのUPDATE/DELETEを実行するにはどうすればいいですか? – gwin003
はIdですが、他のテーブルの外部キーですか? –
はい、私の質問のステートメントを参照してください。 – gwin003