请看下面的代码:
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
无需使用游标。
编辑:想要的输出:
也许1个电话
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年
那么rnd和val在每一行中总是不同的吗?如果是“随机的”,那么有时候它们也会一样。另外,在您提到的2个调用中,rnd在该列上没有所有值是否重要?
—
gbn
它用于从大量真实数据中生成中小型随机演示。是的,可以补充。
—
bernd_k 2011年