আমি কীভাবে একটি নির্বাচনী বিবৃতিতে প্রতিটি সারিতে বিভিন্ন এলোমেলো মান নির্ধারণ করতে পারি?


11

দয়া করে এই কোডটি দেখুন:

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

আপনার নিখুঁত আউটপুট কি হবে দয়া করে? সম্ভবত আমি কিছু মিস করছি
gbn

আমি এটি স্পষ্ট করতে একটি কার্সার সংস্করণ প্রস্তুত করছি
bernd_k

সুতরাং rnd এবং ভাল সবসময় প্রতিটি সারিতে আলাদা হয়? যদি এটি "এলোমেলো" হয় তবে মাঝে মাঝে তারা একই রকম হয় would এছাড়াও, আপনার উল্লিখিত 2 টি কলগুলিতে রেন্ডের কলামে সমস্ত মান নেই তা কি বিবেচনা করে?
জিবিএন

এটি বাস্তব ডেটার একটি বড় পুল থেকে একটি ছোট থেকে মাঝারি র্যান্ডম প্রদর্শন তৈরি করতে ব্যবহৃত হয়। হ্যাঁ repletions অনুমোদিত হয়।
bernd_k

উত্তর:


11

একটি subquery সম্ভব হলে একবার মূল্যায়ন করা হয়। "ফিচার" কী বলে (ভাঁজ?) দুঃখিত বলে মনে করতে পারছি না।

একইটি GETDATE এবং RAND ফাংশনে প্রযোজ্য। NEWID সারিবদ্ধভাবে সারিবদ্ধভাবে মূল্যায়ন করা হয় কারণ এটি অভ্যন্তরীণভাবে একটি এলোমেলো মান এবং এটি কখনও কখনও একই মান উত্পন্ন করে না।

সাধারন কৌশলগুলি হ'ল চেকসুমের ইনপুট হিসাবে বা র্যান্ডের জন্য বীজ হিসাবে নিউআইডি ব্যবহার করা

প্রতি সারিতে এলোমেলো মানের জন্য:

SELECT
   co1l, col2,
   ABS(CHECKSUM(NEWID())) AS Random1,
   RAND(CHECKSUM(NEWID())) AS Random2
FROM
   MyTable

আপনি যদি এলোমেলো অর্ডার চান:

SELECT
   co1l, col2
FROM
   MyTable
ORDER BY
   NEWID()

আপনি যদি সারি অর্ডার সহ এলোমেলো অর্ডার চান তবে। ফলসেটের আদেশ নির্বিশেষে এখানে প্রকৃত অর্ডার অর্ডার সংরক্ষণ করা হয়

SELECT
   id, val,
   ROWNUMBER() OVER (ORDER BY id) AS id
FROM
   #t1
ORDER BY
   NEWID()

সম্পাদনা:

এই ক্ষেত্রে, আমরা প্রয়োজনীয়তাটি নিম্নরূপভাবে বলতে পারি:

  1. সেটটিতে প্রতিটি সারির জন্য সেট থেকে যে কোনও র্যান্ডম মানটি ফিরিয়ে দিন
  2. এলোমেলো মান যে কোনও সারির প্রকৃত মান থেকে আলাদা হবে

এটি আমি উপরে উপস্থাপিত থেকে পৃথক যা সাধারণভাবে বিভিন্ন উপায়ে সারিগুলি পুনরায় অর্ডার করে

সুতরাং, আমি ক্রসের আবেদন বিবেচনা করব। WHOWE ধারাটি সারির মূল্যায়ন অনুসারে সারি সারি করে এবং "ভাঁজ" সমস্যাটি এড়িয়ে যায় এবং নিশ্চিত করে যে ভাল এবং rnd সর্বদা আলাদা থাকে are ক্রস প্রয়োগ খুব ভাল স্কেল করতে পারেন

SELECT
   id, val, R.rnd
FROM
   #t1 t1
   CROSS APPLY
   (SELECT TOP 1 val as rnd FROM #t1 t2 WHERE t1.val <> t2.val ORDER BY NEWID()) R
ORDER BY
   id

প্রযোজ্য SQL সার্ভার 2005 এবং উপরের
bernd_k

1
@ বার্নড_ কে: হ্যাঁ, তবে ২০১১ সালে এসকিউএল সার্ভার 2000 ব্যবহারকারীদের উপেক্ষা করা বাস্তবসম্মত হওয়া উচিত ...
জিবিএন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.