একটি ডাটাবেস টেবিল (টি-এসকিউএল) থেকে এলোমেলো রেকর্ড


85

স্কয়ার সার্ভার টেবিল থেকে এলোমেলো রেকর্ড পুনরুদ্ধার করার কি কোনও সংযোগ উপায় আছে?

আমি আমার ইউনিট পরীক্ষার ডেটাটি এলোমেলো করতে চাই, তাই একটি টেবিল থেকে একটি এলোমেলো আইডি নির্বাচন করার জন্য একটি সহজ উপায় খুঁজছি। ইংরাজীতে, নির্বাচনটি হবে "টেবিলের একটি আইডি নির্বাচন করুন যেখানে আইডিটি টেবিলের সর্বনিম্ন আইডি এবং টেবিলের সর্বোচ্চ আইডির মধ্যে একটি র্যান্ডম সংখ্যা number"

আমি কোয়েরি চালানো ছাড়া এটি করার কোনও উপায় বের করতে পারি না, নাল মানটির জন্য পরীক্ষা করতে হবে, তারপরে নাল হলে পুনরায় চালাও।

ধারনা?


এখানে বেশ
মেষ

4
আপনি কি নিশ্চিত যে আপনি এই পদ্ধতির গ্রহণ করতে চান? ইউনিট পরীক্ষার ডেটা এলোমেলো হওয়া উচিত নয় - প্রকৃতপক্ষে, আপনি ইউনিট পরীক্ষাটি যতবার চালান না কেন একই ফলাফল পাওয়ার গ্যারান্টি দেওয়া উচিত। এলোমেলো তথ্য থাকা ইউনিট পরীক্ষার এই মৌলিক নীতি লঙ্ঘন করতে পারে।
মূক্ত

@ মেশের উপরের লিঙ্কটি আর সক্রিয় নেই।
রবার্ট সিভার্স

উত্তর:


146

স্কয়ার সার্ভার টেবিল থেকে এলোমেলো রেকর্ড পুনরুদ্ধার করার কি কোনও সংযোগ উপায় আছে?

হ্যাঁ

SELECT TOP 1 * FROM table ORDER BY NEWID()

ব্যাখ্যা

A NEWID()প্রতিটি সারির জন্য উত্পন্ন হয় এবং টেবিলটি এটির দ্বারা সাজানো হয়। প্রথম রেকর্ডটি ফিরে আসবে (অর্থাত্ "সর্বনিম্ন" জিইউইডি সহ রেকর্ড)।

মন্তব্য

  1. চারটি সংস্করণ থেকে জিইউইডিগুলি সিউডো-এলোমেলো সংখ্যা হিসাবে উত্পন্ন হয়:

    4 ইউআইডি সংস্করণটি সত্যই-এলোমেলো বা সিউডো-এলোমেলো সংখ্যা থেকে ইউআইডিগুলি তৈরি করার জন্য for

    অ্যালগরিদম নিম্নরূপ:

    • ঘড়ির_সেক_হী_আর_রক্ষিত দুটি সবচেয়ে উল্লেখযোগ্য বিট (6 বিট 6 এবং 7) যথাক্রমে শূন্য এবং একটিতে সংরক্ষিত করুন।
    • বিভাগ 4.1.3 থেকে 4-বিট সংস্করণ সংখ্যায় সময়_হী_আর_বর্তন ক্ষেত্রের চারটি উল্লেখযোগ্য বিট (12 থেকে 15 বিট) সেট করুন।
    • অন্যান্য সমস্ত বিটগুলি এলোমেলোভাবে (বা সিউডো-এলোমেলোভাবে) নির্বাচিত মানগুলিতে সেট করুন।

    - একটি সর্বজনীন ইউনিক আইডেন্টিফায়ার (ইউইউডি) ইউআরএন নেমস্পেস - আরএফসি 4122

  2. বিকল্পটি SELECT TOP 1 * FROM table ORDER BY RAND()যেমন ভাববে তেমন কার্যকর হবে না। RAND()প্রতি ক্যোয়ারীতে একটি একক মান প্রদান করে, সুতরাং সমস্ত সারি একই মান ভাগ করবে।

  3. যদিও জিইউইডি মানগুলি সিউডো-এলোমেলো, তত বেশি চাহিদাযুক্ত অ্যাপ্লিকেশনগুলির জন্য আপনার আরও ভাল পিআরএনজি প্রয়োজন।

  4. সাধারণ কর্মক্ষমতা প্রায় 10,000,000 সারিগুলির জন্য 10 সেকেন্ডেরও কম - অবশ্যই সিস্টেমের উপর নির্ভর করে। নোট করুন যে কোনও সূচকে আঘাত করা অসম্ভব, সুতরাং কর্মক্ষমতা তুলনামূলকভাবে সীমাবদ্ধ থাকবে।


ঠিক আমি খুঁজছেন ছিল কি. আমি এটি তৈরি করার চেয়ে সহজ ছিল বলে আমার মনে হয়েছিল।
জেরেমি

4
আপনি ধরে নিচ্ছেন যে NEWID সিউডোর্যান্ডম মান তৈরি করে। এটির যথাযথ মানগুলি উত্পন্ন করার একটি ভাল সুযোগ রয়েছে। NEWID কেবল অনন্য মান তৈরি করে। RAND তবে ছদ্ম র্যান্ডম মান উত্পন্ন করে।
স্কিজেড

আমি এটি 1,671,145 টি সারি সহ একটি ভারী সূচকযুক্ত টেবিলটিতে চালাচ্ছি এবং ফিরে আসতে 7 সেকেন্ড সময় লাগে। টেবিলটিও বেশ অনুকূল - এটি কার্যত আমাদের ডাটাবেসের কেন্দ্রস্থল তাই এটি যত্ন নেওয়া হয়েছে।
টম রিটার

@ Âভিউ নতুন ১. select মিলিয়ন সারি এবং select সেকেন্ড এমন একটি নির্বাচন যা কোনও সূচককে হিট করে না (এবং পারে না) এটি খারাপ নয়।
Sklivvz

7
@ স্কিজ, র‌্যান্ড এর মতো কাজ করে না। নির্বাচনের আগে একটি একক এলোমেলো মান উত্পন্ন হয়। সুতরাং যদি আপনি "নির্বাচন করুন শীর্ষ 10 টি র‌্যান্ড () ..." চেষ্টা করেন তবে আপনি সর্বদা একই মান পাবেন
Sklivvz

27

বৃহত্তর টেবিলগুলিতে আপনি TABLESAMPLEপুরো টেবিলটি স্ক্যান করা এড়াতে এর জন্য এটি ব্যবহার করতে পারেন ।

SELECT  TOP 1 *
FROM YourTable
TABLESAMPLE (1000 ROWS)
ORDER BY NEWID()

ORDER BY NEWIDএখনও ঠিক ফিরে সারি যে ডেটা পৃষ্ঠাতে প্রথমে হাজির এড়াতে প্রয়োজন।

ব্যবহারের জন্য নম্বরটি টেবিলের আকার এবং সংজ্ঞা জন্য সাবধানতার সাথে বেছে নেওয়া দরকার এবং যদি কোনও সারি ফিরে না আসে তবে আপনি আবার চেষ্টা করার যুক্তি বিবেচনা করতে পারেন। এর পিছনে গণিত এবং কেন কৌশলটি ছোট টেবিলগুলির জন্য উপযুক্ত নয় এটি এখানে আলোচনা করা হয়েছে


আমি মাইক্রোসফ্টের ওয়েবসাইটে এটি পেয়েছি: নীচের শর্তগুলির মধ্যে যে কোনও একটি সত্য হলে আপনি একটি বড় টেবিল থেকে দ্রুত নমুনা ফিরিয়ে আনতে ট্যাবস্যাম্পল ব্যবহার করতে পারেন: স্বতন্ত্র সারিগুলির স্তরে নমুনাটিকে সত্যিকারের এলোমেলো নমুনা হতে হবে না। সারণীর পৃথক পৃষ্ঠাগুলি সারি একই পৃষ্ঠায় অন্যান্য সারিগুলির সাথে সম্পর্কিত নয়।
মার্ক এন্টিং

4
@ মারকইন্টিং - TOP 1একই পৃষ্ঠায় সারিগুলি পরস্পর সম্পর্কযুক্ত কিনা সে ক্ষেত্রে এটি কোনও ব্যাপার নয়। আপনি কেবল তাদের মধ্যে একটি বাছাই করছেন।
মার্টিন স্মিথ

9

এমআইএন (আইডি) এবং ম্যাক্স (আইডি) এবং তারপরে র্যান্ডম আইডি পাওয়ার জন্য আপনার পদ্ধতিটি ব্যবহার করে দেখুন

SELECT TOP 1 * FROM table WHERE Id >= @yourrandomid

এটি সর্বদা আপনাকে এক সারি দেবে।


4
-1, এটি কেবল তখনই কাজ করবে যখন ন্যূনতম এবং সর্বোচ্চের মধ্যে কোনও আইডি নেই। যদি কোনওটি মুছে ফেলা হয় তবে একই আইডিটি এলোমেলো ফাংশন দ্বারা উত্পন্ন হয়, আপনি শূন্য রেকর্ড ফিরে পাবেন back
নিল এন

6
@ নীল, সত্যই নয় - এটি আইডি না থাকলে র্যান্ডম সংখ্যার চেয়ে বেশি আইডির সাথে প্রথম সারিটি পেয়ে যাবে। এখানে সমস্যাটি হ'ল প্রতিটি সারি বের হওয়ার সম্ভাবনা স্থির নয়। তবে আবার বেশিরভাগ ক্ষেত্রেই এটি যথেষ্ট ices
Sklivvz

4
+1 ইউনিট পরীক্ষার জন্য যা বিভিন্ন মানকে যথেষ্ট ভাল যেগুলি হিট করা উচিত - যদি আপনি একটি সত্যিকারের এলোমেলো অনুরোধ করেন তবে এটি অন্য কিছু। তবে ওপি প্রসঙ্গে এটি যথেষ্ট ভাল হওয়া উচিত।
টমটম

7

আপনি যদি বড় ডেটাটি নির্বাচন করতে চান তবে আমার জানা সবচেয়ে ভাল উপায় হ'ল:

SELECT * FROM Table1
WHERE (ABS(CAST(
    (BINARY_CHECKSUM
    (keycol1, NEWID())) as int))
    % 100) < 10

সূত্র: এমএসডিএন


আমি নিশ্চিত নই তবে আমি মনে করি সত্যিকারের এলোমেলো সংখ্যা তৈরি করতে RAND () বরং NEWID () ব্যবহার করা নির্বাচন প্রক্রিয়াতে NEWID () ব্যবহারের অসুবিধার কারণে আরও ভাল হতে পারে।
কিউমাস্টার

আমি শতাংশের ভিত্তিতে রেকর্ডের সঠিক সংখ্যার সাথে এই পদ্ধতিটি ব্যবহার করার চেষ্টা করছি, আমি এটি প্রসারিত নির্বাচন পরিসর এবং টপ এন সহ সীমাবদ্ধ করে দিয়েছি, কোনও পরামর্শ আছে কি?
কিউমাস্টার

আমি এই দৃশ্যের সাথে আরও একটি সমস্যা পেয়েছি, আপনি যদি গ্রুপটি ব্যবহার করেন তবে সর্বদা এলোমেলোভাবে নির্বাচিত সারিগুলির একই ক্রম পাবেন, তাই এটি ছোট টেবিলগুলিতে মনে হয় @ সিলভিভিজ পদ্ধতিটি সবচেয়ে উপযুক্ত।
কিউমাস্টার

0

আমি চেষ্টা করেছি যে পদ্ধতিগুলি উন্নত করতে চেয়েছিলাম এবং এই পোস্টটি জুড়ে এসেছি। আমি বুঝতে পারি এটি পুরানো তবে এই পদ্ধতিটি তালিকাভুক্ত নয়। আমি পরীক্ষার ডেটা তৈরি এবং প্রয়োগ করছি; এটি @ এসপি (দুটি চর রাষ্ট্র) এর সাথে ডাকা একটি এসপিতে "ঠিকানা" করার পদ্ধতিটি দেখায়

Create Table ##TmpAddress (id Int Identity(1,1), street VarChar(50), city VarChar(50), st VarChar(2), zip VarChar(5))
Insert Into ##TmpAddress(street, city, st, zip)
Select street, city, st, zip 
From tbl_Address (NOLOCK)
Where st = @st


-- unseeded RAND() will return the same number when called in rapid succession so
-- here, I seed it with a guaranteed different number each time. @@ROWCOUNT is the count from the most recent table operation.

Set @csr = Ceiling(RAND(convert(varbinary, newid())) * @@ROWCOUNT)

Select street, city, st, Right(('00000' + ltrim(zip)),5) As zip
From ##tmpAddress (NOLOCK)
Where id = @csr

0

আপনি যদি সত্যিই পৃথক সারিগুলির একটি এলোমেলো নমুনা চান তবে সারণীটি স্যাম্পল ব্যবহার না করে এলোমেলোভাবে সারিগুলি ফিল্টার করার জন্য আপনার ক্যোয়ারীটি পরিবর্তন করুন। উদাহরণস্বরূপ, নিম্নলিখিত কোয়েরি বিক্রয়ের সারিগুলির প্রায় এক শতাংশ ফেরত দিতে NEWID ফাংশনটি ব্যবহার করে a সেলস অর্ডারডেটেল টেবিল:

SELECT * FROM Sales.SalesOrderDetail
WHERE 0.01 >= CAST(CHECKSUM(NEWID(), SalesOrderID) & 0x7fffffff AS float)
/ CAST (0x7fffffff AS int)

সেলসঅর্ডারআইডি কলামটি চেকসুম এক্সপ্রেশনটিতে অন্তর্ভুক্ত করা হয়েছে যাতে NEWID () প্রতি সারি ভিত্তিতে নমুনা অর্জনের জন্য প্রতি সারিতে একবার মূল্যায়ন করে। CAST (CHECKSUM (NEWID (), SalesOrderID) & 0x7fffffff as float / CAST (0x7fffffff AS int) এক্সপ্রেশনটি 0 এবং 1 এর মধ্যে একটি এলোমেলো ফ্লোট মানকে মূল্যায়ন করে ""

সূত্র: http://technet.microsoft.com/en-us/library/ms189108(v=sql.105).aspx

এটি নীচে আরও ব্যাখ্যা করা হয়েছে:

কিভাবে কাজ করে? আসুন যেখানে বিভাজন বিভক্ত করা এবং এটি ব্যাখ্যা।

CHECKSUM ফাংশন তালিকার আইটেমগুলির চেয়ে একটি চেকসাম গণনা করছে। সেলসঅর্ডারআইড এমনকি প্রয়োজনীয় কিনা তা নিয়ে বিতর্কযোগ্য, যেহেতু NEWID () এমন একটি ফাংশন যা একটি নতুন এলোমেলো জিআইডি ফিরিয়ে দেয়, সুতরাং একটি ধ্রুবক দ্বারা একটি এলোমেলো চিত্রকে গুণ করা যে কোনও ক্ষেত্রে এলোমেলো হতে পারে। প্রকৃতপক্ষে, বিক্রয় ওর্ডারআইডি বাদ দিলে কোনও পার্থক্য নেই বলে মনে হচ্ছে। যদি আপনি আগ্রহী পরিসংখ্যানবিদ হন এবং এটির অন্তর্ভুক্তিকে ন্যায়সঙ্গত করতে পারেন তবে দয়া করে নীচের মন্তব্যগুলি বিভাগটি ব্যবহার করুন এবং আমাকে কেন ভুল করছেন তা আমাকে জানান!

CHECKSUM ফাংশন একটি ভারবিনারি প্রদান করে। বাইনারি (111111111 ...) এর সমতুল্য 0x7fffffff দিয়ে কিছুটা বিপরীতভাবে এবং অপারেশন করা, একটি দশমিক মান দেয় যা কার্যকরভাবে 0 এবং 1 এর এলোমেলো স্ট্রিংয়ের প্রতিনিধিত্ব করে। সহ-দক্ষ 0x7fffffff দ্বারা বিভাজন কার্যকরভাবে এই দশমিক চিত্রটিকে 0 এবং 1 এর মধ্যে একটি চিত্রকে কার্যকর করে তোলে এবং তারপরে প্রতিটি সারি চূড়ান্ত ফলাফলের সেটটিতে অন্তর্ভুক্তির যোগ্যতা রয়েছে কিনা তা সিদ্ধান্ত নেওয়ার জন্য, 1 / x এর একটি প্রান্তিক ব্যবহৃত হয় (এই ক্ষেত্রে, 0.01) যেখানে নমুনা হিসাবে পুনরুদ্ধার করার জন্য x শতাংশের পরিমাণ is

উত্স: https://www.mssqltips.com/sqlservertip/3157/different-ways-to-get-random-data-for-sql-server-data-sampling

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.