使用不同的随机选择的数字更新每一行

时间:2017-03-27 07:02:10

标签: sql sql-server sql-server-2008

更新查询;

Update Table_1
set Value_1 = (select top 1 Rand_Value from Table_2 Order By newid())

此更新为每个要更新的行分配相同的随机选择值。

有没有办法用

中的不同值为每个正在更新的行分配

表2随机?

2 个答案:

答案 0 :(得分:4)

一种方法是使用ROW_NUMBER()NEWID()的几个常用表格表达式:

创建并填充样本表(在将来的问题中保存此步骤):

DECLARE @T1 as table
(
    col1 char(1)
)

DECLARE @T2 as table 
(
    col1 char(1)
)


INSERT INTO @T1 VALUES 
(NULL), (''), (' '), 
(NULL), (''), (' '), 
(NULL), (''), (' '), 
(NULL), (''), (' ')


INSERT INTO @T2 VALUES 
('a'), ('b'), ('c'), 
('d'), ('e'), ('f'), 
('g'), ('h'), ('i')

公用表表达式:

;WITH CTE1 AS
(
    SELECT  Col1, 
            ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) rn
    FROM @T1
), CTE2 AS
(
    SELECT  t2.Col1, 
            ROW_NUMBER() OVER(ORDER BY NEWID()) rn
    FROM @T2 t2
    CROSS JOIN @T1 -- Note: the cross join here is to get at least the same amount of records as there are in @T1
)

更新声明:

UPDATE t1
SET col1 = t2.Col1
FROM CTE1 t1
INNER JOIN CTE2 t2 ON t1.rn = t2.rn

You can see a live demo on rextester

答案 1 :(得分:2)

回答这部分问题(此更新为每个正在更新的行分配相同的随机选择值。)。请参阅下面的演示脚本..

我在表1和表2中填充了100行(连续整数),并且我在脚本下执行,与您拥有的相同。

Table1 has  1 to 100  
table2 has  20 to 100

现在我在脚本下执行,根据你应该更新每行的随机值

update t1
set t1.id=(select top 1 id from #t2 Order By newid())
from #t1 t1

现在除了你,每一行都要分配一个随机值。下面是我得到的输出

id 
75
75
75
....

整个表使用相同的值更新,但是随机,每次执行更新时都会更改此值

为什么sql server选择这样做。让我们看看执行计划

enter image description here

该计划是简单的嵌套循环,但SQL选择使用Lazy spool来存储数据。

现在,如果仔细观察一下,在这个计划中,还有两个属性Rebind和Rewind.Below是他们拥有的价值

enter image description here

重新绑定意味着 - 由于数据已更改,SQL必须多次进入主表并填充此假脱机(在本例中),

倒带意味着 - SQL服务器选择使用此线轴本身多少次,而不用触及主表

SQLserver选择在你的情况下进行99次倒带,并选择仅使用来自延迟假脱机的数据,因为数据没有改变,因为你编写查询的方式

现在,如果您重写了如下所示的更新,您将获得所期望的行为,因为这些值是相关的

update t1
set t1.id=(select top 1 id from #t2 t2 where t1.id=t2.id Order By newid())
from #t1 t1

以上查询导致了以下执行计划

enter image description here

您也可以观察由于相关性而产生的重新数量

enter image description here

演示脚本:

drop table if exists #t1;
drop table if exists #t2;

create table #t1
(id int
)

create table #t2
(id int
)


insert into #t1
select top 100 * from numbers
order by n

insert into #t2
select top 100 * from numbers where n>20
order by n

update t1
set t1.id=(select top 1 id from #t2 t2 where t1.id=t2.id Order By newid())
from #t1 t1


select * from #t1