【问题标题】:Simple update statement so that all rows are assigned a different value简单的更新语句,以便为所有行分配不同的值
【发布时间】:2012-10-16 19:36:42
【问题描述】:

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

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

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

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

【问题讨论】:

  • table1 是否有<= table2 中的行数?
  • 那么不可能每一行都得到不同的table2Id值。
  • @MartinSmith 你是对的,但正如你从我的例子中看到的那样,我希望他们每个人都随机获得一个值。并非所有的值都相同。
  • 啊误解了你的要求。 table1的主键是什么?

标签: sql sql-server


【解决方案1】:

在一些测试台上,你的原始计划如下所示。

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

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

对我来说,这个计划没有线轴。

重要的是关联来自table1 的唯一字段,但是,即使添加了线轴,它也必须始终回弹而不是重绕(重播最后一个结果),因为每行的相关值都不同。

如果表很大,这会很慢,因为所需的工作是两个表行的乘积(对于table1 中的每一行,它需要对table2 进行全面扫描)

【讨论】:

  • 这确实有效。谢谢。我不知道 SQL Server 是否试图检查该值是否动态相关。有趣的。它的速度大约是我的循环解决方案的 4 倍。
【解决方案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

【讨论】:

  • 这种方法应该比我的更快(我想在我的答案中提供类似的替代方案),但需要调整以应对table1 中的更多行而不是table2。它还将具有不同的特征,因为每个数字都是随机分配的,不包括已经分配的那些,而不是从完整集合中随机分配的。
  • @MartinSmith - 谢谢,我没想过会为两行分配相同的id 的情况。如果是用于测试,这可能不是问题,但值得牢记。
【解决方案3】:

分解并使用循环。这很有效,虽然速度很慢。

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

【讨论】:

    【解决方案4】:

    我将假设基于前 1 的 MS SQL:

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

    (抱歉,未测试)

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-02
    • 1970-01-01
    相关资源
    最近更新 更多