이 코드를보십시오 :
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