2017-03-27 1 views

答えて

4

一つの方法は、ROW_NUMBER()NEWID()と共通テーブル式のカップルを使用することです:

サンプル表を作成し、移入(私たちのセーブくださいあなたの将来の質問では、このステップ):

DECLARE @T1 as table 
(
    col1 char(1) 
) 

DECLARE @T2 as table 
(
    col1 char(1) 
) 


INSERT INTO @T1 VALUES 
(NULL), (''), (' '), 
(NULL), (''), (' '), 
(NULL), (''), (' '), 
(NULL), (''), (' ') 


INSERT INTO @T2 VALUES 
('a'), ('b'), ('c'), 
('d'), ('e'), ('f'), 
('g'), ('h'), ('i') 

共通テーブル式:

;WITH CTE1 AS 
(
    SELECT Col1, 
      ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) rn 
    FROM @T1 
), CTE2 AS 
(
    SELECT t2.Col1, 
      ROW_NUMBER() OVER(ORDER BY NEWID()) rn 
    FROM @T2 t2 
    CROSS JOIN @T1 -- Note: the cross join here is to get at least the same amount of records as there are in @T1 
) 

更新ステートメント。:ちょうど(。このアップデートは、各行が更新されることに同じランダムに選ばれた値を代入する)質問のこの部分に答えるデモスクリプトは、以下を参照してください。..

を私は人口

UPDATE t1 
SET col1 = t2.Col1 
FROM CTE1 t1 
INNER JOIN CTE2 t2 ON t1.rn = t2.rn 

You can see a live demo on rextester

+0

おかしい事は、テーブル変数とOPのクエリがあまりにも、動作することです。オプティマイザは、実際のテーブル変数とはかなり異なるテーブル変数を扱うようです。一方のクエリは両方ともうまく動作します。 –

2

あなたが持っているものと同じ、私は、スクリプトの下に実行する100行(シーケンシャル整数)表1と表2の両方と..

Table1 has 1 to 100 
table2 has 20 to 100 

は、今私は、SCRの下に実行しましたあなたはあなたを除いては、各行がランダムvalue..belowを割り当てられるようにすることを今、各行

update t1 
set t1.id=(select top 1 id from #t2 Order By newid()) 
from #t1 t1 

のためのランダムな値を更新する必要がありに従ってIPTは、私が

id 
75 
75 
75 
.... 

全体得た出力でありますテーブルには、同じ値で更新されますが、ランダムには、この値は、毎回あなたは、SQL Serverが行うことを選択する理由

がthis.Letsは、実行計画を見ての更新プログラムを実行に変更されます

enter image description here

プランは単純なネストループですが、SQLはレイジースプールを使用してデータを格納することを選択します。

この計画では、2つ以上のプロパティRebind and Rewindがあります。データは

巻き戻しを変更したため、SQLは、(この場合は)メインテーブルに行くと、このスプールを移入した回数 - 以下は、彼らが再バインドが意味

enter image description here

を持って評価されています手段 - 何回SQL Serverがメインテーブルに触れることなくこのスプール自体を使用するように選択

SQLserverデータのハッシュではないため、99の巻き戻しを選択し、レイジースプールのデータのみを使用することを選択しますあなたの質問を書いた方法のために変更されていません

値が相関しているので、3210

は今、あなたは以下のようなあなたの更新プログラムを書き直した場合、あなたが期待している目的の動作を取得します、

update t1 
set t1.id=(select top 1 id from #t2 t2 where t1.id=t2.id Order By newid()) 
from #t1 t1 

上記のクエリは

enter image description here

実行計画の下での結果

また、あなたが相関

enter image description here

による再バインドの数を観察することができます

デモスクリプト:

drop table if exists #t1; 
drop table if exists #t2; 

create table #t1 
(id int 
) 

create table #t2 
(id int 
) 


insert into #t1 
select top 100 * from numbers 
order by n 

insert into #t2 
select top 100 * from numbers where n>20 
order by n 

update t1 
set t1.id=(select top 1 id from #t2 t2 where t1.id=t2.id Order By newid()) 
from #t1 t1 


select * from #t1 
関連する問題