3

テスト目的で、あるテーブルの列をランダムな外部キーに設定しようとしています。以下のクエリを使用してみました

update table1 set table2Id = (select top 1 table2Id from table2 order by NEWID())

これにより、1 つの table2Id がランダムに取得され、各行の table1 の外部キーとして割り当てられます。それはほとんど私が望むものですが、各行が異なる table2Id 値を取得するようにします。

table1 の行をループすることでこれを行うことができますが、もっと簡潔な方法があることはわかっています。

4

4 に答える 4

8

いくつかのテストテーブルでは、元の計画は次のようになります。

原案

結果を 1 回だけ計算し、それを sppol にキャッシュしてから、その結果を再生します。次のことを試して、SQL Server がサブクエリを相関関係があり、外側の行ごとに再評価する必要があると見なすようにすることができます。

UPDATE table1
SET    table2Id = (SELECT TOP 1 table2Id
                   FROM   table2
                   ORDER  BY Newid(),
                             table1.table1Id)

私にとっては、スプールなしでこの計画を提供します。

新プラン

table1ただし、相関値は行ごとに異なるため、スプールが追加された場合でも、巻き戻す (最後の結果を再生する) のではなく常にリバウンドする必要があるように、固有のフィールドで相関させることが重要です。

テーブルが大きい場合、必要な作業は 2 つのテーブルの行の積であるため、これは遅くなります (その中の行ごとにtable1のフル スキャンを実行する必要がありますtable2) 。

于 2012-10-16T20:33:15.093 に答える
2

最初の回答が不完全だったので、もう一度回答します。

を割り当てるまで 2 つのテーブルを結合する方法は他にないため、と の両方に一時キーを与えるためにtable2_id使用できます。row_numbertable1table2

with
 t1 as (
  select row_number() over (order by table1_id) as row, table1_id
  from table1 )
,
t2 as (
  select row_number() over (order by NEWID()) as row, table2_id 
  from table2 )

update table1
set table2_id = t2.table2_id
from t1 inner join t2
on t1.row = t2.row

select * from table1

それをテストする SQL Fiddle: http://sqlfiddle.com/#!6/bf414/12

于 2012-10-16T20:40:42.823 に答える
0

壊れてループを使用しました。非常に遅いですが、これは機能しました。

Select *
Into   #Temp
From   table1

Declare @Id int

While (Select Count(*) From #Temp) > 0
Begin

    Select Top 1 @Id = table1Id From #Temp

    update table1 set table2Id = (select top 1 table2Id from table2 order by NEWID()) where table1Id = @Id

    Delete #Temp Where table1Id = @Id

End
drop table #Temp
于 2012-10-16T20:36:38.277 に答える
-1

トップ1に基づいてMSSQLを想定します。

update table1 
set table2Id = 
  (select top 1 table2Id from table2 tablesample(1 percent))

(申し訳ありませんが、テストされていません)

于 2012-10-16T19:39:51.120 に答える