Bitte schauen Sie sich diesen Code an:
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');
Nun, wann immer Sie dies ausführen
select *,
( select top 1 val from #t1 order by NEWID()) rnd
from #t1 order by 1;
Sie erhalten ein Ergebnis, bei dem alle Zeilen den gleichen Zufallswert haben. z.B
id val rnd
----------- ---------- ----------
1 a b
2 b b
3 c b
4 d b
Ich kenne eine Möglichkeit, mit einem Cursor die Zeilen zu schleifen und verschiedene Zufallswerte zu erhalten, aber das ist nicht performant.
Eine clevere Lösung dafür ist
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
Aber ich habe die Abfrage vereinfacht. Die eigentliche Abfrage sieht eher so aus
select *,
( select top 1 val from t2 where t2.x <> t1.y order by NEWID()) rnd
from t1 order by 1;
und die einfache Lösung passt nicht. Ich suche nach einer Möglichkeit, eine wiederholte Bewertung von zu erzwingen
( select top 1 val from #t1 order by NEWID()) rnd
ohne die Verwendung von Cursorn.
Bearbeiten: Gewünschte Ausgabe:
vielleicht 1 Anruf
id val rnd
----------- ---------- ----------
1 a c
2 b c
3 c b
4 d a
und ein zweiter Anruf
id val rnd
----------- ---------- ----------
1 a a
2 b d
3 c d
4 d b
Der Wert für jede Zeile sollte nur ein zufälliger Wert sein, der von den anderen Zeilen unabhängig ist
Hier ist die Cursorversion des Codes:
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