একটি এসকিএল ডাটাবেস থেকে সাধারণ র্যান্ডম নমুনা


93

আমি কীভাবে এসকিউএল এ দক্ষ একটি সহজ এলোমেলো নমুনা গ্রহণ করব? প্রশ্নে থাকা ডাটাবেসগুলি মাইএসকিউএল চলছে; আমার টেবিলটি কমপক্ষে 200,000 সারি এবং আমি প্রায় 10,000 এর একটি সাধারণ এলোমেলো নমুনা চাই।

"সুস্পষ্ট" উত্তরটি হ'ল:

SELECT * FROM table ORDER BY RAND() LIMIT 10000

বড় টেবিলগুলির জন্য, এটি খুব ধীর: এটি RAND()প্রতিটি সারিটির জন্য কল করে (এটি ইতিমধ্যে এটি ও (এন) এ রাখে), এবং এগুলি সাজায়, এটিকে সর্বোত্তমভাবে ও (এন এলজি এন) তৈরি করে। এটি ও (এন) এর চেয়ে দ্রুত করার কোনও উপায় আছে?

দ্রষ্টব্য : অ্যান্ড্রু মাও মন্তব্যগুলিতে যেমন উল্লেখ করেছেন, আপনি যদি এসকিউএল সার্ভারে এই পদ্ধতির ব্যবহার করেন তবে আপনার টি-এসকিউএল ফাংশনটি ব্যবহার করা উচিত NEWID(), কারণ র্যান্ড () সমস্ত সারিগুলির জন্য একই মান ফিরে আসতে পারে

সম্পাদনা: 5 বছর পিছনে

আমি আবার একটি বড় টেবিল নিয়ে এই সমস্যায় পড়েছি এবং @ অজ্ঞদের সমাধানের একটি সংস্করণ ব্যবহার করে শেষ করেছি, দুটি টুইট সহ:

  • সুলভ সস্তায়, আমার কাঙ্ক্ষিত নমুনার আকারটি 2-5x সারিগুলিতে নমুনা করুন ORDER BY RAND()
  • RAND()প্রতিটি সন্নিবেশ / আপডেটে একটি সূচিযুক্ত কলামে ফলাফল সংরক্ষণ করুন । (যদি আপনার ডেটা সেটটি খুব আপডেট-ভারী না হয় তবে এই কলামটি সতেজ রাখার জন্য আপনাকে অন্য কোনও উপায় খুঁজে নিতে হতে পারে))

কোনও টেবিলের 1000-আইটেমের নমুনা নিতে, আমি সারিগুলি গণনা করি এবং ফলাফলটি হিমায়িত_র্যান্ড কলামের সাথে গড়ে 10,000 টি সারি নিচে নামিয়ে রাখি:

SELECT COUNT(*) FROM table; -- Use this to determine rand_low and rand_high

  SELECT *
    FROM table
   WHERE frozen_rand BETWEEN %(rand_low)s AND %(rand_high)s
ORDER BY RAND() LIMIT 1000

(আমার আসল বাস্তবায়নে আমি নিচে নমুনা নিচ্ছি না তা নিশ্চিত করার জন্য এবং র্যান্ড_এইচটি হাতের কাছে ম্যানুয়ালি মোড়ানোর জন্য আরও কাজ জড়িত, তবে প্রাথমিক ধারণাটি "এলোমেলোভাবে আপনার এন কে কয়েক হাজারে কেটে ফেলুন।")

এটি কিছু ত্যাগ স্বীকার করার সময়ে, এটি আমাকে ORDER BY RAND()আবার সূচি স্ক্যান ব্যবহার করে ডেটাবেসকে নমুনা করতে দেয়, যতক্ষণ না এটি আবার যথেষ্ট পরিমাণে ছোট হয়।


4
এটি এসকিউএল সার্ভারেও কাজ করে না কারণ RAND()পরবর্তী প্রতিটি কল একই মান দেয়।
অ্যান্ড্রু মাও

4
ভাল পয়েন্ট - আমি একটি নোট যুক্ত করব যে এসকিউএল সার্ভার ব্যবহারকারীদের পরিবর্তে নতুন () দ্বারা অর্ডার ব্যবহার করা উচিত।
ওজ্রাক

এটি এখনও মারাত্মকভাবে অক্ষম কারণ এটি সমস্ত ডেটা বাছাই করতে হয়েছে। কিছু শতাংশের জন্য একটি এলোমেলো স্যাম্পলিং কৌশলটি আরও ভাল তবে আমি এখানে বেশ কয়েকটি পোস্ট পড়ার পরেও, আমি একটি গ্রহণযোগ্য সমাধান খুঁজে পাইনি যা যথেষ্ট পরিমাণে এলোমেলো।
অ্যান্ড্রু মাও

আপনি যদি প্রশ্নটি পড়ে থাকেন তবে আমি বিশেষত জিজ্ঞাসা করছি কারণ অর্ডার বাই র‌্যান্ড () ও (এন এলজি এন)।
ওজ্রাক

নীচে মুপোসাতের উত্তরটি দুর্দান্ত যদি আপনি খুব বেশি পরিমাণে র‌্যান্ড () এর পরিসংখ্যানিক র্যান্ডমনেস নিয়ে আচ্ছন্ন না হন।
জোশ গ্রিফার

উত্তর:


25

এখানে এই ধরণের সমস্যা সম্পর্কে খুব আকর্ষণীয় আলোচনা রয়েছে: http://www.titov.net/2005/09/21/do-not-use-order-by-rand-or-how-to-get-random-rows-from-table/

আমি মনে করি যে টেবিলটি সম্পর্কে আপনার কোনও ধারণা নেই যে আপনার ও (এন এলজি এন) সমাধানটি সবচেয়ে ভাল। যদিও একটি ভাল অপ্টিমাইজার বা কিছুটা আলাদা কৌশল সহ আপনার তালিকার ক্যোয়ারীটি কিছুটা ভাল হতে পারে, ও (এম * এন) যেখানে এম পছন্দসই এলোমেলো সারিগুলির সংখ্যা, কারণ এটি প্রয়োজনীয়ভাবে পুরো বৃহত অ্যারেটি বাছাই করতে হবে না would , এটি কেবলমাত্র ক্ষুদ্রতম সময়ের জন্য অনুসন্ধান করতে পারে। তবে আপনি যে সংখ্যার পোস্ট করেছেন সেগুলির জন্য এম এম lg n এর চেয়েও বড়।

তিনটি ধারণা যা আমরা চেষ্টা করতে পারি:

  1. সারণীতে একটি অনন্য, সূচকযুক্ত, প্রাথমিক কী রয়েছে

  2. আপনি (এম) নির্বাচন করতে চান এলোমেলো সারিগুলির সংখ্যা টেবিলের সারিগুলির সংখ্যার তুলনায় অনেক ছোট (এন)

  3. অনন্য প্রাথমিক কীটি একটি পূর্ণসংখ্যা যা 1 থেকে n এর মধ্যে কোনও ফাঁক ছাড়াই হয়

কেবল অনুমান 1 এবং 2 দিয়ে আমার মনে হয় এটি ও (এন) এ করা যেতে পারে, যদিও ধারনা 3 মেলাতে আপনাকে টেবিলে একটি সম্পূর্ণ সূচি লিখতে হবে, সুতরাং এটি সম্ভবত দ্রুত ও (এন) নয়। যদি আমরা টেবিলটি সম্পর্কে আরও কিছু সুন্দরভাবে ধরে নিতে পারি তবে আমরা ও (এম লগ এম) এ কাজটি করতে পারি। অনুমান 3 এর সাথে কাজ করার জন্য একটি সহজ সুন্দর অতিরিক্ত সম্পত্তি হবে। একটি দুর্দান্ত এলোমেলো সংখ্যার জেনারেটর সহ যে কোনও সারিতে এম সংখ্যা তৈরি করার সময় কোনও নকলের গ্যারান্টি নেই, একটি হে (এম) সমাধান সম্ভব হবে।

তিনটি অনুমান দেওয়া, মূল ধারণাটি 1 এবং n এর মধ্যে এম অনন্য এলোমেলো সংখ্যা তৈরি করা এবং তারপরে টেবিল থেকে সেই কীগুলি সহ সারিগুলি নির্বাচন করুন। আমার কাছে এখনই আমার সামনে মাইএসকিএল বা কিছু নেই, তাই সামান্য সিউডোকোডে এটি এমন কিছু দেখাচ্ছে:


create table RandomKeys (RandomKey int)
create table RandomKeysAttempt (RandomKey int)

-- generate m random keys between 1 and n
for i = 1 to m
  insert RandomKeysAttempt select rand()*n + 1

-- eliminate duplicates
insert RandomKeys select distinct RandomKey from RandomKeysAttempt

-- as long as we don't have enough, keep generating new keys,
-- with luck (and m much less than n), this won't be necessary
while count(RandomKeys) < m
  NextAttempt = rand()*n + 1
  if not exists (select * from RandomKeys where RandomKey = NextAttempt)
    insert RandomKeys select NextAttempt

-- get our random rows
select *
from RandomKeys r
join table t ON r.RandomKey = t.UniqueKey

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


আমি এলোমেলো কী নির্বাচনের উপর একটি অনন্য সূচক যুক্ত করার পরামর্শ দিচ্ছি এবং সম্ভবত সন্নিবেশের অনুলিপিগুলি উপেক্ষা করে আপনি পৃথক জিনিস থেকে মুক্তি পেতে পারেন এবং যোগদানটি দ্রুত হবে।
স্যাম জাফরন

আমি মনে করি এলোমেলো নম্বর অ্যালগোরিদম কিছু টুইট ব্যবহার করতে পারে - হয় উল্লিখিত হিসাবে একটি অনন্য বাধা, অথবা কেবল 2 * মিটার সংখ্যা উত্পন্ন করে, এবং নির্ধারিত নির্বাচন করুন, আইডি দ্বারা অর্ডার (প্রথম আসুন-প্রথম পরিবেশন করুন, সুতরাং এটি অনন্যতম সীমাবদ্ধতা হ্রাস করে) ) সীমাবদ্ধ মি। আমি এটা পছন্দ করি.
ojrac

এলোমেলো কী নির্বাচনের ক্ষেত্রে একটি অনন্য সূচক যুক্ত করতে এবং তারপরে অনুলিপিগুলি উপেক্ষা করার জন্য, আমি ভেবেছিলাম এটি আপনাকে একটি সাজানোর জন্য ও (এম এলজি এম) এর পরিবর্তে ও (এম ^ 2) আচরণে ফিরিয়ে আনতে পারে। একবারে এলোমেলো সারি সন্নিবেশ করানোর সময় সার্ভার সূচকটি কতটা দক্ষ বজায় রাখছে তা নিশ্চিত নয়।
ব্যবহারকারী 12861

2 * মিটার সংখ্যা বা কিছু উত্পন্ন করার পরামর্শ হিসাবে, আমি কোনও অ্যালগরিদম চেয়েছিলাম যা কাজই করার গ্যারান্টিযুক্ত। আপনার 2 * মিটার এলোমেলো সংখ্যায় এম ডুপ্লিকেট বেশি থাকায় সর্বদা (স্লিম) সম্ভাবনা থাকে, সুতরাং আপনার প্রশ্নের জন্য আপনার পর্যাপ্ত পরিমাণ নেই।
ব্যবহারকারী 12861

4
আপনি টেবিলের সারিগুলির সংখ্যা কীভাবে পাবেন?
আশ্চর্যজনক-

54

আমি মনে করি দ্রুততম সমাধানটি

select * from table where rand() <= .3

এখানে কাজটি করা উচিত বলে আমি মনে করি।

  • এটি প্রতিটি সারির জন্য একটি এলোমেলো সংখ্যা তৈরি করবে। সংখ্যাটি 0 থেকে 1 এর মধ্যে
  • এটি উত্পন্ন সংখ্যা 0 এবং .3 (30%) এর মধ্যে থাকলে সেই সারিটি প্রদর্শন করতে হবে কিনা তা মূল্যায়ন করে।

এটি ধরে নিয়েছে যে র‌্যান্ড () একটি অভিন্ন বিতরণে সংখ্যা উত্পন্ন করছে। এটি এটি করার দ্রুততম উপায়।

আমি দেখেছি যে কেউ সমাধানের প্রস্তাব দিয়েছিল এবং তারা প্রমাণ ছাড়াই গুলি করে মেরে ফেলেছে .. এখানে আমি যা বলব তা হল -

  • এটি ও (এন) তবে কোনও বাছাইয়ের প্রয়োজন নেই সুতরাং এটি ও (এন lg এন) এর চেয়ে দ্রুত
  • mysql প্রতিটি সারির জন্য এলোমেলো সংখ্যা তৈরি করতে খুব সক্ষম। এটা চেষ্টা কর -

    INFORMATION_SCHEMA থেকে র্যান্ড () নির্বাচন করুন। টেবিলস সীমা 10;

যেহেতু প্রশ্নে থাকা ডাটাবেসটি মাইএসকিউএল, তাই এটি সঠিক সমাধান।


4
প্রথমত, আপনার সমস্যাটি যে সত্যিকার অর্থে প্রশ্নের উত্তর দেয় না, যেহেতু এটি অর্ধ-এলোমেলো ফলাফল ফিরে পেয়েছে, একটি পছন্দসই সংখ্যার কাছাকাছি হলেও সঠিক সংখ্যার ফলাফলের পরিবর্তে ঠিক সেই সংখ্যাটি নয়।
ব্যবহারকারী 12861

4
পরবর্তী, দক্ষতার হিসাবে, আপনার ও (এন), যেখানে n হ'ল টেবিলের সারিগুলির সংখ্যা। এটি ও (এম লগ এম) এর মতো প্রায় ভাল নয়, যেখানে এম আপনার পছন্দ ফলাফলের সংখ্যা এবং এম << এন। আপনি এখনও ঠিক থাকতে পারতেন যে এটি অনুশীলনে আরও দ্রুত হবে, কারণ আপনি যেমন র্যান্ড () গুলি তৈরি করছেন এবং ধ্রুবকভাবে তাদের তুলনা করছেন খুব দ্রুত হতে পারে। এটি পরীক্ষা করতে আপনাকে পরীক্ষা করতে হবে। ছোট টেবিলের সাহায্যে আপনি জিততে পারেন। বিশাল টেবিল এবং অনেক কম সংখ্যক পছন্দসই ফলাফল নিয়ে আমি সন্দেহ করি।
ব্যবহারকারী 12861

4
যদিও @ ব্যবহারকারী 12861 এটি সঠিক সঠিক নম্বর না পাওয়া সম্পর্কে সঠিক, যদিও ডান রুক্ষ আকারে সেট করা ডেটা কাটা ভাল উপায় way
ojrac

4
কীভাবে ডাটাবেসগুলি নিম্নলিখিত কোয়েরিতে পরিষেবা দেয় - SELECT * FROM table ORDER BY RAND() LIMIT 10000 ? এটি প্রথমে প্রতিটি সারির জন্য একটি এলোমেলো সংখ্যা তৈরি করতে হবে (আমার বর্ণিত সমাধানের সমান), তারপরে এটি অর্ডার করুন .. ধরণের ব্যয়বহুল! এই কারণেই এই সমাধানটি আমি বর্ণিত একটিটির চেয়ে ধীর হয়ে যাবে, কারণ কোনও প্রকারের প্রয়োজন নেই। আমি বর্ণিত সমাধানটিতে আপনি সীমাবদ্ধ করতে পারেন এবং এটি আপনাকে সারি সংখ্যার চেয়ে বেশি দেয় না। যেহেতু কেউ সঠিকভাবে নির্দেশ করেছেন, এটি আপনাকে সঠিক নমুনার আকার দেয় না, তবে এলোমেলো নমুনার সাথে, প্রায়শই প্রায়শই কোনও কঠোর প্রয়োজন হয় না।
অজ্ঞ

ন্যূনতম সংখ্যার সংখ্যা নির্দিষ্ট করার কোনও উপায় আছে কি?
সিএমসিডিগ্রাগনকাই

5

স্পষ্টতই এসকিউএল এর কয়েকটি সংস্করণে একটি TABLESAMPLEকমান্ড রয়েছে তবে এটি সমস্ত এসকিউএল বাস্তবায়নে নেই (উল্লেখযোগ্যভাবে, রেডশিফ্ট)।

http://technet.microsoft.com/en-us/library/ms189108(v=sql.105).aspx


খুব ঠান্ডা! দেখে মনে হচ্ছে এটি পোস্টগ্রিএসকিউএল বা মাইএসকিউএল / মারিয়াডিবি দ্বারা প্রয়োগ করা হয়নি তবে আপনি যদি এসকিউএল বাস্তবায়ন করে যা এটি সমর্থন করে তবে এটি দুর্দান্ত উত্তর answer
ওজরাক

আমি বুঝতে পারি যে TABLESAMPLEপরিসংখ্যানগত দিক থেকে এলোমেলো নয়।
শান

4

শুধু ব্যবহার

WHERE RAND() < 0.1 

রেকর্ডের 10% পেতে বা

WHERE RAND() < 0.01 

রেকর্ডগুলির 1% পেতে


4
এটি প্রতিটি সারির জন্য আরএএনএন্ডকে ও (এন) তৈরি করবে। পোস্টারটি তার থেকে আরও ভাল কিছু খুঁজছিল।
ব্যবহারকারী 12861

4
কেবল RAND()এটিই নয়, পরবর্তী কলগুলির জন্য কমপক্ষে একই মানটি প্রদান করে (কমপক্ষে এমএসএসকিউএল তে), এর অর্থ আপনি পুরো টেবিলটি পাবেন বা সম্ভাব্যতা সহ এটির কোনওটিই পাবেন না।
অ্যান্ড্রু মাও

4

আরএন্ডের চেয়ে আরও দ্রুত অর্ডার ()

আমি এই পদ্ধতিটি তুলনায় অনেক দ্রুত হতে ORDER BY RAND()পেরেছি তাই এটি ও (এন) এ চলে সময়ে এবং এত চিত্তাকর্ষকভাবে দ্রুত হয়।

Http://technet.microsoft.com/en-us/library/ms189108%28v=sql.105%29.aspx থেকে :

নন-এমএসএসকিউএল সংস্করণ - আমি এটি পরীক্ষা করিনি

SELECT * FROM Sales.SalesOrderDetail
WHERE 0.01 >= RAND()

এমএসএসকিউএল সংস্করণ:

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

এটি রেকর্ডের ~ 1% নির্বাচন করবে। সুতরাং আপনার যদি নির্বাচিত হওয়ার জন্য সঠিক # পার্সেন্ট বা রেকর্ডের প্রয়োজন হয় তবে কিছুটা সুরক্ষা মার্জিনের সাথে আপনার শতাংশের অনুমান করুন, তারপরে এলোমেলোভাবে আরও ব্যয়বহুল ORDER BY RAND()পদ্ধতিটি ব্যবহার করে ফলাফল সেট থেকে অতিরিক্ত রেকর্ডগুলি সংগ্রহ করুন ।

এমনকি দ্রুততর

আমি আরও এই পদ্ধতিটি আরও উন্নত করতে সক্ষম হয়েছি কারণ আমার একটি সুপরিচিত সূচকযুক্ত কলাম মান সীমা ছিল।

উদাহরণস্বরূপ, আপনার যদি সমানভাবে বিতরণকৃত পূর্ণসংখ্যার [0..max] সহ একটি সূচক কলাম থাকে তবে আপনি এটিকে এলোমেলোভাবে ছোট ছোট অন্তরগুলি নির্বাচন করতে পারেন। প্রতিটি ক্যোয়ারি রান চালানোর জন্য আলাদা সেট পেতে আপনার প্রোগ্রামে এইটিকে গতিশীল করুন। এই উপসেট নির্বাচনটি ও (এন) হবে , যা আপনার সম্পূর্ণ ডেটা সেটের তুলনায় প্রস্থের অনেকগুলি অর্ডারকে কম করতে পারে।

আমার পরীক্ষায় আমি শুল্ক দ্বারা অর্ডার ব্যবহার করে 3 মিনিট থেকে 20 (20 মিলির বাইরে) নমুনা রেকর্ড পাওয়ার প্রয়োজনীয় সময়টি 0.0 সেকেন্ডে হ্রাস করে !


1

আমি উল্লেখ করতে চাই যে এই সমস্ত সমাধানগুলি প্রতিস্থাপন ছাড়াই নমুনায় প্রদর্শিত হয়। এলোমেলো ক্রম থেকে শীর্ষ কে সারি নির্বাচন করা বা এলোমেলো ক্রমে স্বতন্ত্র কী রয়েছে এমন টেবিলে যোগদান করা প্রতিস্থাপন ছাড়াই উত্পন্ন এলোমেলো নমুনা অর্জন করবে।

আপনি যদি নিজের নমুনাটি স্বাধীন হতে চান তবে আপনাকে প্রতিস্থাপনের সাথে নমুনা করতে হবে। ব্যবহারকারী 12861 এর সমাধানের অনুরূপ একটি JOIN ব্যবহার করে এটি কীভাবে করা যায় তার একটি উদাহরণের জন্য প্রশ্ন 25451034 দেখুন । সমাধান টি-এসকিউএল জন্য লেখা হয়, তবে ধারণাটি কোনও এসকিউএল ডিবিতে কাজ করে।


0

একটি সেটের উপর ভিত্তি করে আমরা একটি সারণির আইডিস (যেমন গণনা 5) পুনরুদ্ধার করতে পারি তা পর্যবেক্ষণ দিয়ে শুরু:

select *
from table_name
where _id in (4, 1, 2, 5, 3)

আমরা ফলাফলটিতে আসতে পারি যে যদি আমরা স্ট্রিং তৈরি করতে পারি "(4, 1, 2, 5, 3)", তবে আমাদের চেয়ে আরও কার্যকর উপায় থাকবেRAND()

উদাহরণস্বরূপ, জাভাতে:

ArrayList<Integer> indices = new ArrayList<Integer>(rowsCount);
for (int i = 0; i < rowsCount; i++) {
    indices.add(i);
}
Collections.shuffle(indices);
String inClause = indices.toString().replace('[', '(').replace(']', ')');

যদি আইডির ফাঁক থাকে, তবে প্রাথমিক অ্যারেলিস্টটি indicesহ'ল আইডিতে কোনও স্কেল কোয়েরির ফলাফল।


0

আপনার যদি হুবহু mসারিগুলির প্রয়োজন হয় তবে বাস্তবিকভাবে আপনি এসকিউএল এর বাইরে আপনার আইডিগুলির উপসেট তৈরি করবেন। বেশিরভাগ পদ্ধতির "nth" এন্ট্রি নির্বাচন করার জন্য এক পর্যায়ে প্রয়োজন হয় এবং এসকিউএল টেবিলগুলি আসলেই অ্যারে হয় না। ভাবনাটি হলো এই যে চাবি শুধু করার জন্য পরপর হয় 1 এর মধ্যে র্যান্ডম আছে ints যোগ দিতে এবং গণনা এছাড়াও সন্তুষ্ট করা কঠিন - মাইএসকিউএল উদাহরণস্বরূপ নেটিভ এটা সমর্থন করে না, এবং লক শর্ত ... চতুর

কেবল একটি সরল BTREE কী ধরে ধরে এখানে একটি O(max(n, m lg n))সময়কালীন, O(n)স্পেস সমাধান:

  1. আপনার পছন্দের স্ক্রিপ্টিং ভাষার কোনও অ্যারেতে ডাটা টেবিলের মূল কলামের সমস্ত মান আনুন O(n)
  2. একটি সঞ্চালন ফিশার-ইয়েটস এলোমেলো পর বাঁধন mঅদলবদল, এবং subarray নিষ্কর্ষ [0:m-1]মধ্যেϴ(m)
  3. মূল ডেটাসেট (উদাহরণস্বরূপ SELECT ... WHERE id IN (<subarray>)) এর সাথে সুব্রায় "যোগ দিন"O(m lg n)

যে কোনও পদ্ধতি যা এসকিউএল এর বাইরে এলোমেলো উপসেট জেনারেট করে কমপক্ষে এই জটিলতা থাকতে হবে। O(m lg n)বিটিআরইয়ের চেয়ে যোগটি কোনও দ্রুততর হতে পারে না (সুতরাং O(m)দাবিগুলি বেশিরভাগ ইঞ্জিনগুলির জন্য ফ্যান্টাসি) এবং এলোমেলো নীচে আবদ্ধ হয় nএবংm lg n অ্যাসিপোটোটিক আচরণকে প্রভাবিত করে না।

পাইথোনিক সিউডোকোডে:

ids = sql.query('SELECT id FROM t')
for i in range(m):
  r = int(random() * (len(ids) - i))
  ids[i], ids[i + r] = ids[i + r], ids[i]

results = sql.query('SELECT * FROM t WHERE id IN (%s)' % ', '.join(ids[0:m-1])

0

Netezza এ 3000 এলোমেলো রেকর্ড নির্বাচন করুন:

WITH IDS AS (
     SELECT ID
     FROM MYTABLE;
)

SELECT ID FROM IDS ORDER BY mt_random() LIMIT 3000

কিছু এসকিউএল ডায়ালেক্ট-নির্দিষ্ট নোট যুক্ত করা ছাড়াও, আমি 'অর্ডার বাই র্যান্ড () লিমিটেড without 1' ছাড়াই সারিগুলির একটি এলোমেলো নমুনাটি কীভাবে জিজ্ঞাসা করব তার প্রশ্নের উত্তর বলে আমি মনে করি না।
ওজরাক

0

চেষ্টা করুন

SELECT TOP 10000 * FROM table ORDER BY NEWID()

এটি কি খুব বেশি জটিল না হয়ে কাঙ্ক্ষিত ফলাফল দেবে?


নোটটি NEWID()টি-এসকিউএল-র সাথে নির্দিষ্ট।
পিটার ও।

আমার ক্ষমা। এইটা. ধন্যবাদ এটা জানা কেউ যদি এখানে খুঁজছি আমি একটি ভাল উপায় করেনি আসে তবে দরকারী, ও টি-এসকিউএল ব্যবহার করছে
Northernlad

ORDER BY NEWID()কার্যত একইরূপে ORDER BY RAND()- এটি RAND()সেটের প্রতিটি সারির জন্য আহ্বান করে - O (n) - এবং তারপরে পুরো জিনিসটি বাছাই করে - O (n lg n)। অন্য কথায়, এটি সবচেয়ে খারাপ ক্ষেত্রে সমাধান যা এই প্রশ্নটির উন্নতি করতে দেখছে।
ojrac

0

মাইক্রোসফ্ট এসকিউএল সার্ভার, পোস্টগ্র্রেএসকিউএল, এবং ওরাকল (তবে মাইএসকিউএল বা এসকিউএলাইট নয়) এর মতো নির্দিষ্ট উপভাষায় আপনি এর মতো কিছু করতে পারেন

select distinct top 10000 customer_id from nielsen.dbo.customer TABLESAMPLE (20000 rows) REPEATABLE (123);

কেবল (10000 rows)এটি ব্যতিরেকে না করার কারণটি topহ'ল TABLESAMPLEযুক্তি আপনাকে সর্বাধিক নিখুঁত সংখ্যক সারি দেয় (যেমন কখনও কখনও 75% যা কখনও কখনও 1.25% বার), তাই আপনি ওভারসাম্পল করতে চান এবং সঠিক সংখ্যাটি নির্বাচন করতে চান। REPEATABLE (123)একটি র্যান্ডম বীজ প্রদানের জন্য।


-4

আপনি করতে পারে

SELECT * FROM table LIMIT 10000 OFFSET FLOOR(RAND() * 190000)

4
দেখে মনে হচ্ছে এটি আমার ডেটাগুলির এলোমেলো টুকরো নির্বাচন করবে; আমি আরও জটিল কিছু সন্ধান করছি - 10,000 এলোমেলোভাবে বিতরণ করা সারি।
ojrac

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