मुझे ओरेकल डीबी से यादृच्छिक रूप से पंक्तियों का चयन करना होगा।
Ex: 100 पंक्तियों के साथ एक तालिका मान लें, मैं पूरे 100 पंक्तियों में से उन रिकॉर्डों में से 20 को कैसे बेतरतीब ढंग से वापस कर सकता हूं।
जवाबों:
SELECT *
FROM (
SELECT *
FROM table
ORDER BY DBMS_RANDOM.RANDOM)
WHERE rownum < 21;
SAMPLE () आपको ठीक 20 पंक्तियाँ देने की गारंटी नहीं है , लेकिन उपयुक्त हो सकती है (और बड़ी तालिका के लिए पूर्ण क्वेरी + सॉर्ट-बाय-रैंडम से बेहतर प्रदर्शन कर सकती है):
SELECT *
FROM table SAMPLE(20);
नोट: 20
यहाँ एक अनुमानित प्रतिशत है, वांछित पंक्तियों की संख्या नहीं। इस मामले में, चूंकि आपके पास 100 पंक्तियाँ हैं, इसलिए लगभग 20 पंक्तियाँ प्राप्त करने के लिए आप 20% नमूना माँगते हैं।
SELECT * FROM table SAMPLE(10) WHERE ROWNUM <= 20;
यह अधिक कुशल है क्योंकि इसमें तालिका को क्रमबद्ध करने की आवश्यकता नहीं है।
बेतरतीब ढंग से 20 पंक्तियों का चयन करने के लिए, मुझे लगता है कि आप बेतरतीब ढंग से ऑर्डर किए गए बहुत सारे का चयन करने और उस सेट के पहले 20 का चयन करने से बेहतर होंगे।
कुछ इस तरह:
Select *
from (select *
from table
order by dbms_random.value) -- you can also use DBMS_RANDOM.RANDOM
where rownum < 21;
छोटे टेबल के लिए सबसे अच्छा इस्तेमाल किया जाता है ताकि डेटा का बड़ा हिस्सा चुनने से बचा जा सके।
संक्षेप में, दो तरीके पेश किए गए थे
1) using order by DBMS_RANDOM.VALUE clause
2) using sample([%]) function
पहले तरीके से 'कोरेक्टनेस' में फायदा होता है, जिसका अर्थ है कि अगर आप वास्तव में मौजूद हैं, तो आपको कभी भी परिणाम नहीं मिलेगा, जबकि दूसरे तरीके से आपको कोई परिणाम नहीं मिल सकता है, हालांकि इसमें सैंपलिंग के दौरान सूचना कम होने के बाद से क्वेरी की स्थिति संतोषजनक होती है।
दूसरे तरीके से 'इफिसिएंट' में फायदा होता है, जिसका मतलब है कि आप तेजी से परिणाम प्राप्त करेंगे और अपने डेटाबेस को हल्का भार देंगे। मुझे डीबीए की ओर से एक चेतावनी दी गई थी कि पहले तरीके का उपयोग करके मेरी क्वेरी डेटाबेस को भार देती है
आप अपनी रुचि के अनुसार दो में से एक तरीका चुन सकते हैं!
Dbms_random.value द्वारा छँटाई के साथ विशाल तालिकाओं के मानक तरीके के मामले में प्रभावी नहीं है क्योंकि आपको पूरी तालिका स्कैन करने की आवश्यकता है और dbms_random.value बहुत धीमी गति से कार्य करता है और संदर्भ स्विच की आवश्यकता होती है। ऐसे मामलों के लिए, 3 अतिरिक्त विधियाँ हैं:
1: उपयोग sample
खंड:
उदाहरण के लिए:
select *
from s1 sample block(1)
order by dbms_random.value
fetch first 1 rows only
अर्थात सभी ब्लॉकों का 1% प्राप्त करें, फिर उन्हें यादृच्छिक रूप से सॉर्ट करें और केवल 1 पंक्ति वापस करें।
2: यदि आपके पास सामान्य वितरण के साथ कॉलम पर एक इंडेक्स / प्राथमिक कुंजी है , तो आप न्यूनतम और अधिकतम मान प्राप्त कर सकते हैं, इस रेंज में यादृच्छिक मान प्राप्त कर सकते हैं और उस यादृच्छिक रूप से उत्पन्न मान से अधिक या बराबर मूल्य वाली पहली पंक्ति प्राप्त कर सकते हैं।
उदाहरण:
--big table with 1 mln rows with primary key on ID with normal distribution:
Create table s1(id primary key,padding) as
select level, rpad('x',100,'x')
from dual
connect by level<=1e6;
select *
from s1
where id>=(select
dbms_random.value(
(select min(id) from s1),
(select max(id) from s1)
)
from dual)
order by id
fetch first 1 rows only;
3: रैंडम टेबल ब्लॉक प्राप्त करें, उपद्रवी उत्पन्न करें और इस पंक्ति द्वारा तालिका से पंक्ति प्राप्त करें :
select *
from s1
where rowid = (
select
DBMS_ROWID.ROWID_CREATE (
1,
objd,
file#,
block#,
1)
from
(
select/*+ rule */ file#,block#,objd
from v$bh b
where b.objd in (select o.data_object_id from user_objects o where object_name='S1' /* table_name */)
order by dbms_random.value
fetch first 1 rows only
)
);
यहां बताया गया है कि प्रत्येक समूह से यादृच्छिक नमूना कैसे लिया जाए:
SELECT GROUPING_COLUMN,
MIN (COLUMN_NAME) KEEP (DENSE_RANK FIRST ORDER BY DBMS_RANDOM.VALUE)
AS RANDOM_SAMPLE
FROM TABLE_NAME
GROUP BY GROUPING_COLUMN
ORDER BY GROUPING_COLUMN;
मुझे यकीन नहीं है कि यह कितना कुशल है, लेकिन अगर आपके पास बहुत सी श्रेणियां और उप-श्रेणियां हैं, तो यह काम अच्छी तरह से करने लगता है।
टेबल
SELECT * FROM
(
SELECT column_name FROM table_name
ORDER BY dbms_random.value
)
WHERE rownum = 1;