我正在尝试将一个表中的列设置为随机外键以进行测试。我尝试使用以下查询
update table1 set table2Id = (select top 1 table2Id from table2 order by NEWID())
这将随机获得一个 table2Id 并将其分配为 table1 中每一行的外键。这几乎是我想要的,但我希望每一行都获得不同的 table2Id 值。
我可以通过遍历 table1 中的行来做到这一点,但我知道有一种更简洁的方法。
我正在尝试将一个表中的列设置为随机外键以进行测试。我尝试使用以下查询
update table1 set table2Id = (select top 1 table2Id from table2 order by NEWID())
这将随机获得一个 table2Id 并将其分配为 table1 中每一行的外键。这几乎是我想要的,但我希望每一行都获得不同的 table2Id 值。
我可以通过遍历 table1 中的行来做到这一点,但我知道有一种更简洁的方法。
在一些测试表上,我的最终计划如下所示。
它只计算一次结果并将其缓存在 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
)
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
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
我将假设基于前 1 的 MS SQL:
update table1
set table2Id =
(select top 1 table2Id from table2 tablesample(1 percent))
(抱歉,未测试)