3

我正在尝试将一个表中的列设置为随机外键以进行测试。我尝试使用以下查询

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

这将随机获得一个 table2Id 并将其分配为 table1 中每一行的外键。这几乎是我想要的,但我希望每一行都获得不同的 table2Id 值。

我可以通过遍历 table1 中的行来做到这一点,但我知道有一种更简洁的方法。

4

4 回答 4

8

在一些测试表上,我的最终计划如下所示。

原计划

它只计算一次结果并将其缓存在 sppol 中,然后重放该结果。您可以尝试以下操作,以便 SQL Server 将子查询视为相关的并且需要重新评估每个外部行。

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

For me that gives this plan without the spool.

新计划

It is important to correlate on a unique field from table1 however so that even if a spool is added it must always be rebound rather than rewound (replaying the last result) as the correlation value will be different for each row.

If the tables are large this will be slow as work required is a product of the two table's rows (for each row in table1 it needs to do a full scan of table2)

于 2012-10-16T20:33:15.093 回答
2

I'm having another go at answering this, since my first answer was incomplete.

As there is no other way to join the two tables until you assign the table2_id you can use row_number to give a temporary key to both table1 and table2.

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

Broke down and used a loop for it. This worked, although it was very slow.

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 的 MS SQL:

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

(抱歉,未测试)

于 2012-10-16T19:39:51.120 回答