ओरेकल डेटाबेस से रिकॉर्ड कैसे प्राप्त करें?


82

मुझे ओरेकल डीबी से यादृच्छिक रूप से पंक्तियों का चयन करना होगा।

Ex: 100 पंक्तियों के साथ एक तालिका मान लें, मैं पूरे 100 पंक्तियों में से उन रिकॉर्डों में से 20 को कैसे बेतरतीब ढंग से वापस कर सकता हूं।

जवाबों:


111
SELECT *
FROM   (
    SELECT *
    FROM   table
    ORDER BY DBMS_RANDOM.RANDOM)
WHERE  rownum < 21;

1
मुझे इससे हराएं। हालांकि यह केवल तालिका से पहली 20 पंक्तियों का चयन करेगा और उन्हें यादृच्छिक रूप से आदेश देगा।
निशांत शर्मा

10
आपको यह जानना होगा कि यह बड़ी टेबलों पर एक बहुत भारी ऑपरेशन है, क्योंकि यह सबसे पहले EACH रो को एक रैंडम नंबर देगा, फिर इस वैल्यू पर सॉर्ट करेगा और फिर इसमें से कुछ रिकॉर्ड लेगा।
Roeland Van Heddegem

11
@ निशांतशर्मा, पंक्तियों को यादृच्छिक किया जाता है, फिर सीमित - आपकी टिप्पणी सही नहीं है।
साइमन M SimonKenzie

6
यह दृष्टिकोण बहुत धीमा है
इवान क्रॉस्के

1
@JonBetts, मुझे लगता है कि नमूना बहुत तेज़ और अधिक संसाधन-कुशल है: stackoverflow.com/a/9920431/156787
इवान क्रोसके

50

SAMPLE () आपको ठीक 20 पंक्तियाँ देने की गारंटी नहीं है , लेकिन उपयुक्त हो सकती है (और बड़ी तालिका के लिए पूर्ण क्वेरी + सॉर्ट-बाय-रैंडम से बेहतर प्रदर्शन कर सकती है):

SELECT *
FROM   table SAMPLE(20);

नोट: 20यहाँ एक अनुमानित प्रतिशत है, वांछित पंक्तियों की संख्या नहीं। इस मामले में, चूंकि आपके पास 100 पंक्तियाँ हैं, इसलिए लगभग 20 पंक्तियाँ प्राप्त करने के लिए आप 20% नमूना माँगते हैं।


1
नमूना तेज है, लेकिन बहुत यादृच्छिक प्रतीत नहीं होता है। तालिका के शीर्ष / शुरुआत की ओर रिकॉर्ड पसंदीदा होते हैं।
क्रेगर्स84

1
यदि आप क्वेरी को पूर्ण तालिका के माध्यम से प्राप्त करने से पहले रोकते हैं तो यह होगा।
जेफरी केम्प

2
क्षमा करें, मैंने एक गलती की है, आपकी पोस्ट ठीक है और परिणाम समान रूप से वितरित किए गए हैं। जब आप नमूना (20) के साथ संयोजन में "जहां पंक्तिबद्ध <= 20" जोड़ते हैं, तो डेटा कम यादृच्छिक होने लगता है।
१०:२१ पर क्रेग्स ४४

14
SELECT * FROM table SAMPLE(10) WHERE ROWNUM <= 20;

यह अधिक कुशल है क्योंकि इसमें तालिका को क्रमबद्ध करने की आवश्यकता नहीं है।


7
20 पंक्तियों के बाद नमूने को रोकने के परिणामस्वरूप गैर-यादृच्छिक परिणाम होंगे (तालिका में पहले पाई गई पंक्तियां बाद के लोगों की तुलना में कहीं अधिक बार वापस आ जाएंगी)। साथ ही, यह 20 पंक्तियों को वापस करने की गारंटी नहीं है।
जेफरी केम्प


4

बेतरतीब ढंग से 20 पंक्तियों का चयन करने के लिए, मुझे लगता है कि आप बेतरतीब ढंग से ऑर्डर किए गए बहुत सारे का चयन करने और उस सेट के पहले 20 का चयन करने से बेहतर होंगे।

कुछ इस तरह:

Select *
  from (select *
          from table
         order by dbms_random.value) -- you can also use DBMS_RANDOM.RANDOM
 where rownum < 21;

छोटे टेबल के लिए सबसे अच्छा इस्तेमाल किया जाता है ताकि डेटा का बड़ा हिस्सा चुनने से बचा जा सके।


3

संक्षेप में, दो तरीके पेश किए गए थे

1) using order by DBMS_RANDOM.VALUE clause
2) using sample([%]) function

पहले तरीके से 'कोरेक्टनेस' में फायदा होता है, जिसका अर्थ है कि अगर आप वास्तव में मौजूद हैं, तो आपको कभी भी परिणाम नहीं मिलेगा, जबकि दूसरे तरीके से आपको कोई परिणाम नहीं मिल सकता है, हालांकि इसमें सैंपलिंग के दौरान सूचना कम होने के बाद से क्वेरी की स्थिति संतोषजनक होती है।

दूसरे तरीके से 'इफिसिएंट' में फायदा होता है, जिसका मतलब है कि आप तेजी से परिणाम प्राप्त करेंगे और अपने डेटाबेस को हल्का भार देंगे। मुझे डीबीए की ओर से एक चेतावनी दी गई थी कि पहले तरीके का उपयोग करके मेरी क्वेरी डेटाबेस को भार देती है

आप अपनी रुचि के अनुसार दो में से एक तरीका चुन सकते हैं!


1

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
      )
);

0

यहां बताया गया है कि प्रत्येक समूह से यादृच्छिक नमूना कैसे लिया जाए:

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;

मुझे यकीन नहीं है कि यह कितना कुशल है, लेकिन अगर आपके पास बहुत सी श्रेणियां और उप-श्रेणियां हैं, तो यह काम अच्छी तरह से करने लगता है।


-1
हमें कुछ प्रश्नों का उपयोग करना होगा जो हमें यादृच्छिक कॉलम देगा

टेबल

हमारे पास टीचर टेबल है

ओरेकल सिंटेक्स

SELECT * FROM   
(
SELECT column_name FROM table_name  
ORDER BY dbms_random.value
)  
WHERE rownum = 1;

बेहतर समझ के लिए स्क्रीनशॉट का पालन करें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.