我正在尝试将一个表中的列设置为随机外键以进行测试。 我尝试使用以下查询
update table1 set table2Id = (select top 1 table2Id from table2 order by NEWID())
这将随机获得一个table2Id,并将其作为table1中的外键分配给每一行。 这几乎就是我想要的,但我希望每一行都能获得不同的table2Id值。
我可以通过遍历table1中的行来完成此操作,但我知道有一种更简洁的方法。
答案 0 :(得分:8)
在某些测试表上,我的结束原始计划如下所示。
它只计算一次结果并将其缓存在sppol中然后重放该结果。您可以尝试以下操作,以便SQL Server将子查询视为相关的,并且需要为每个外行重新评估。
UPDATE table1
SET table2Id = (SELECT TOP 1 table2Id
FROM table2
ORDER BY Newid(),
table1.table1Id)
对我来说,这个计划没有假脱机。
重要的是关联来自table1
的唯一字段,但是即使添加了一个假脱机,它也必须始终被反弹而不是重绕(重放最后的结果),因为每个字段的相关值都不同行。
如果表格很大,这将会很慢,因为所需的工作是两个表格行的乘积(对于table1
中的每一行,它需要对table2
进行全面扫描
答案 1 :(得分:2)
我还有另外一个回答这个问题,因为我的第一个回答是不完整的。
由于在分配table2_id
之前没有其他方法可以加入这两个表,因此您可以使用row_number
为table1
和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小提琴测试它:http://sqlfiddle.com/#!6/bf414/12
答案 2 :(得分: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
答案 3 :(得分:-1)
我将假设MS SQL基于前1:
update table1
set table2Id =
(select top 1 table2Id from table2 tablesample(1 percent))
(抱歉,未经测试)