# 如何在SELECT语句的每一行中分配不同的随机值？

11

``````create table #t1(
id int identity (1,1),
val varchar(10)
);

insert into #t1 values ('a');
insert into #t1 values ('b');
insert into #t1 values ('c');
insert into #t1 values ('d');``````

``````select *,
( select top 1 val from #t1 order by NEWID()) rnd
from #t1 order by 1;``````

``````id          val        rnd
----------- ---------- ----------
1           a          b
2           b          b
3           c          b
4           d          b``````

``````select t1.id, t1.val, t2.val
from #t1 t1
join (select *, ROW_NUMBER() over( order by NEWID()) lfd from #t1) as t2 on  t1.id = t2.lfd ``````

``````select *,
( select top 1 val from t2 where t2.x <> t1.y order by NEWID()) rnd
from t1 order by 1;``````

``( select top 1 val from #t1 order by NEWID()) rnd ``

``````id          val        rnd
----------- ---------- ----------
1           a          c
2           b          c
3           c          b
4           d          a``````

``````id          val        rnd
----------- ---------- ----------
1           a          a
2           b          d
3           c          d
4           d          b``````

``````CREATE TABLE #res ( id INT, val VARCHAR(10), rnd VARCHAR(10));

DECLARE @id INT
DECLARE @val VARCHAR(10)
DECLARE c CURSOR FOR
SELECT id, val
FROM #t1
OPEN c
FETCH NEXT FROM c INTO @id, @val
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO #res
SELECT @id, @val, ( SELECT TOP 1 val FROM #t1 ORDER BY NEWID()) rnd
FETCH NEXT FROM c INTO @id, @val
END
CLOSE c
DEALLOCATE c

SELECT * FROM #res``````

gbn

bernd_k 2011年

gbn

bernd_k 2011年

11

GETDATE和RAND函数也是如此。NEWID逐行求值，因为它本质上是一个随机值，并且永远不会两次生成相同的值。

``````SELECT
co1l, col2,
ABS(CHECKSUM(NEWID())) AS Random1,
RAND(CHECKSUM(NEWID())) AS Random2
FROM
MyTable``````

``````SELECT
co1l, col2
FROM
MyTable
ORDER BY
NEWID()``````

``````SELECT
id, val,
ROWNUMBER() OVER (ORDER BY id) AS id
FROM
#t1
ORDER BY
NEWID()``````

1. 为集合中的每一行返回集合中的任何随机值
2. 随机值将与任何行中的实际值不同

``````SELECT
id, val, R.rnd
FROM
#t1 t1
CROSS APPLY
(SELECT TOP 1 val as rnd FROM #t1 t2 WHERE t1.val <> t2.val ORDER BY NEWID()) R
ORDER BY
id``````

APPLY是SQL Server 2005及更高版本
bernd_k，2011年

1
@bernd_k：是的，但是在2011年忽略SQL Server 2000用户应该是现实的……
gbn