Oracle SELECT TOP 10 रिकॉर्ड


144

मुझे Oracle में SQL कथन के साथ एक बड़ी समस्या है। मैं STORAGE_DB द्वारा दिए गए शीर्ष 10 रिकॉर्ड्स का चयन करना चाहता हूं, जो अन्य चयनित विवरण से सूची में नहीं हैं।

यह सभी रिकॉर्ड के लिए ठीक काम करता है:

SELECT DISTINCT 
  APP_ID, 
  NAME, 
  STORAGE_GB, 
  HISTORY_CREATED, 
  TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') AS HISTORY_DATE  
  FROM HISTORY WHERE 
      STORAGE_GB IS NOT NULL AND 
        APP_ID NOT IN (SELECT APP_ID
                       FROM HISTORY
                        WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') = '06.02.2009') 

लेकिन जब मैं जोड़ रहा हूं

AND ROWNUM <= 10
ORDER BY STORAGE_GB DESC

मुझे किसी प्रकार का "यादृच्छिक" रिकॉर्ड मिल रहा है। मुझे लगता है कि आदेश से पहले सीमा लागू होती है।

क्या किसी के पास कोई अच्छा उपाय है? दूसरी समस्या: यह क्वेरी वास्तव में धीमी है (10k + रिकॉर्ड)


संभावित डुप्लिकेट: stackoverflow.com/questions/2306744/…
APC

जवाबों:


199

आपको निम्न के रूप में अपनी वर्तमान क्वेरी को सबक्विरी में रखना होगा:

SELECT * FROM (
  SELECT DISTINCT 
  APP_ID, 
  NAME, 
  STORAGE_GB, 
  HISTORY_CREATED, 
  TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') AS HISTORY_DATE  
  FROM HISTORY WHERE 
    STORAGE_GB IS NOT NULL AND 
      APP_ID NOT IN (SELECT APP_ID FROM HISTORY WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') ='06.02.2009')
  ORDER BY STORAGE_GB DESC )
WHERE ROWNUM <= 10

ओरेकल वापस आने के बाद परिणाम पर पंक्तिबद्ध लागू होता है ।
आपको परिणाम वापस करने के बाद फ़िल्टर करने की आवश्यकता होती है, इसलिए एक सबक्वेरी की आवश्यकता होती है। टॉप-एन परिणाम प्राप्त करने के लिए आप RANK () फ़ंक्शन का भी उपयोग कर सकते हैं ।

प्रदर्शन के लिए के NOT EXISTSस्थान पर उपयोग करने का प्रयास करें NOT INइसे और देखें


NOT EXISTS इस परिदृश्य में काम नहीं कर रहा है (अमान्य संबंधपरक ऑपरेटर) APP_ID NOT EXISTS (SELEC ...)
opHASnoNAME

3
कुछ लोग कह सकते हैं कि यह लोगों को ओरेकल के लिए बंद करने के लिए उपयुक्त है।
MrBoJangles

2
FETCH NEXT N ROWS ONLYनीचे दिए गए उत्तर की जाँच करें।
मोहनीश

@ पद्मराग: जब एक पंक्ति में एक पंक्ति लागू होती है जैसे कि यह - किसी से चयन करें * जहां कुछ कॉलम = '123' और पंक्ति </ 3 है। क्या यह चयन करने के बाद [SomeTable से जहाँ से कुछ का चयन करें = '123']
शिरगिल फरहान

55

यदि आप Oracle 12c का उपयोग कर रहे हैं, तो उपयोग करें:

केवल अगले N NOW ROWS

SELECT DISTINCT 
  APP_ID, 
  NAME, 
  STORAGE_GB, 
  HISTORY_CREATED, 
  TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') AS HISTORY_DATE  
  FROM HISTORY WHERE 
    STORAGE_GB IS NOT NULL AND 
      APP_ID NOT IN (SELECT APP_ID FROM HISTORY WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') ='06.02.2009')
  ORDER BY STORAGE_GB DESC
FETCH NEXT 10 ROWS ONLY

अधिक जानकारी: http://docs.oracle.com/javadb/10.5.3.0/ref/rrefsqljoffsetfree.html


2
अन्य उत्तर की तुलना में यह सोना है
aswzen

मैं aswzen के साथ सहमत हूँ
ऑस्टिन स्प्रिंगर

1
मैं यह उत्तर १०० अपवित्र देना चाहता हूँ! लेकिन अफसोस, मेरे पास केवल एक पुरस्कार है। एक यह है!
ईडीलोन

23

खराब प्रदर्शन के संबंध में किसी भी चीज की संख्या हो सकती है, और यह वास्तव में एक अलग सवाल होना चाहिए। हालांकि, एक स्पष्ट बात यह है कि एक समस्या हो सकती है:

WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') = '06.02.2009') 

यदि HISTORY_DATE वास्तव में एक तिथि स्तंभ है और यदि इसमें कोई अनुक्रमणिका है तो यह पुनर्लेखन बेहतर प्रदर्शन करेगा:

WHERE HISTORY_DATE = TO_DATE ('06.02.2009', 'DD.MM.YYYY')  

इसका कारण यह है कि डेटाटाइप रूपांतरण B- ट्री इंडेक्स के उपयोग को अक्षम करता है।



11

आपको एक स्पष्ट रूप से यादृच्छिक सेट मिलता है क्योंकि ROWNUM को ORDER BY के समक्ष लागू किया जाता है। तो आपकी क्वेरी पहली दस पंक्तियाँ लेती है और उन्हें छाँटती है। उन टॉप टेन सैलरी को चुनने के लिए जिन्हें आपको एक उपश्रम में एक एनालिटिकल फ़ंक्शन का उपयोग करना चाहिए, फिर उसे फ़िल्टर करें:

 select * from 
     (select empno,
             ename,
             sal,
             row_number() over(order by sal desc nulls last) rnm
    from emp) 
 where rnm<=10
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.