Vui lòng xem mã này:
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');
Bây giờ, bất cứ khi nào bạn thực hiện điều này
select *,
( select top 1 val from #t1 order by NEWID()) rnd
from #t1 order by 1;
bạn sẽ nhận được kết quả với tất cả các hàng có cùng giá trị ngẫu nhiên. ví dụ
id val rnd
----------- ---------- ----------
1 a b
2 b b
3 c b
4 d b
Tôi biết một cách sử dụng một con trỏ để lặp các hàng và nhận các giá trị ngẫu nhiên khác nhau, nhưng đó không phải là hiệu suất.
Một giải pháp thông minh cho vấn đề này là
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
Nhưng tôi đã đơn giản hóa truy vấn. Các truy vấn thực sự trông giống như
select *,
( select top 1 val from t2 where t2.x <> t1.y order by NEWID()) rnd
from t1 order by 1;
và giải pháp đơn giản không phù hợp. Tôi đang tìm cách để buộc đánh giá lặp đi lặp lại
( select top 1 val from #t1 order by NEWID()) rnd
không sử dụng con trỏ
Chỉnh sửa: Đầu ra mong muốn:
có lẽ 1 cuộc gọi
id val rnd
----------- ---------- ----------
1 a c
2 b c
3 c b
4 d a
và một cuộc gọi thứ hai
id val rnd
----------- ---------- ----------
1 a a
2 b d
3 c d
4 d b
Giá trị cho mỗi hàng chỉ là một giá trị ngẫu nhiên độc lập với các hàng khác
Đây là phiên bản con trỏ của mã:
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