2016-05-12 15 views
1

これは、いくつかのテーブルを含めることで説明しやすくなると思います。SQL Server 2012で何百万ものレコードを更新する

表A:

UserId  StoreId 
1   10 
2   20 
3   30 
4   40 

表B:私は表2に入ると、その特定のユーザーについては、表AでStoreIdに一致するようにストアを更新するスクリプトを必要とする

UserId  StoreId 
1   10 
1   20 
1   20 
2   20 
2   10 
2   10 
3   30 
3   40 
3   40 
4   40 
4   30 
4   30 

。結局、私は見るべきです。

表B:

UserId  StoreId 
1   10 
1   10 
1   10 
2   20 
2   20 
2   20 
3   30 
3   30 
3   30 
4   40 
4   40 
4   40 

だから私の質問は、表Bはその中の数百万行の百を持っている、とテーブルAは、約20万行を持っていることを考慮すると、これを行うための最も簡単な方法何ですか?

ありがとうございます!

答えて

5

最良の方法は次のとおりです。

ALTER TABLE Table_B 
DROP COLUMN StoreId 

今、あなたは、もはや重複したデータを保存しているし、あなたがそれを必要とするときあなただけTable_AからStoreIdを得ることができます。

それ以外の場合は、JOINとの単純なUPDATEです:

UPDATE B 
SET 
    StoreId = A.StoreID 
FROM 
    Table_B B 
INNER JOIN TABLE_A A ON A.UserId = B.UserId 

あなたがする必要がある場合は、それはdoesnのように、更新のサイズを削減するために、バッチを実行ループにこれを置くことができますあなたのトランザクションログを氾濫させないでください。それを行うにはいくつかの方法があります。一つの例:

DECLARE 
    @batch_size INT = 10000, 
    @min_user_id INT = 1, 
    @max_user_id INT 

SELECT @max_user_id = MAX(UserId) FROM Table_A 

WHILE (@min_user_id <= @max_user_id) 
BEGIN 
    UPDATE B 
    SET 
     StoreId = A.StoreID 
    FROM 
     Table_B B 
    INNER JOIN TABLE_A A ON A.UserId = B.UserId 
    WHERE 
     B.UserId BETWEEN @min_user_id AND @min_user_id + @batch_size 

    SET @min_user_id = @min_user_id + @batch_size + 1 
END 
+1

非常に良い答え – Lamak

+0

は、私はちょうどで行くと、その列をドロップすることがしたいが、私はそれが作成された多くの年後にこのプロジェクトに代わって入りました。この時点で不必要な列を入力して削除するには、フロントエンドのWebサイトとEDMXにかなりの変更を加える必要があります。 偉大な答え!私は迅速な対応に感謝します! – akaWizzmaster

0
select 1 
while (@@rowcount > 0) 
begin 
    UPDATE top(1000) B 
    SET b.StoreId = A.StoreID 
    FROM Table_B B 
    INNER JOIN TABLE_A A ON A.UserId = B.UserId 
    where b.StoreId <> A.StoreID 
     or b.StoreId is null 
end 
関連する問題