कृपया इस कोड को देखें:
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