このコードを見てください:
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
そして2回目の呼び出し
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
それで、rndとvalは常にすべての行で異なりますか?それが「ランダム」である場合、時々それらは同じでした。また、言及した2つの呼び出しでは、rndが列にすべての値を持たないことが重要ですか?
—
gbn 2011年
これは、実際のデータの大きなプールから小規模から中規模のランダムなデモを生成するために使用されます。はい補充は許可されています。
—
bernd_k