मैं Oracle में शीर्ष 1 कैसे करूँ?


251

मैं निम्नलिखित कैसे करूँ?

select top 1 Fname from MyTbl

में ओरेकल 11g ?




3
क्या आप हमें वह आदेश बता सकते हैं जिसके अनुसार आप 'शीर्ष 1' चाहते हैं?
एंड्रयू वुल्फ

1
सबसे पहले आपको कभी भी डीबी इंजन पर भरोसा नहीं करना चाहिए। यदि आप ऐसी चीजों को जानना चाहते हैं, तो एक सीक्वेंसर में डालें। जब आप ऐसा करते हैं, तो यह गारंटी दी जाती है कि उन्हें उस क्रम में क्रमांकित किया जाएगा, जिसे उन्होंने डाला था।
फ्लाइंगगुय

1
इस विषय पर बहुत उपयोगी
Ilia Maskov

जवाबों:


257

यदि आप केवल पहली चयनित पंक्ति चाहते हैं, तो आप निम्न कर सकते हैं:

select fname from MyTbl where rownum = 1

आप शीर्ष एक्स को ऑर्डर करने और लेने के लिए विश्लेषणात्मक कार्यों का उपयोग कर सकते हैं:

select max(fname) over (rank() order by some_factor) from MyTbl

54
यह अच्छा है यदि आप केवल 1 पंक्ति चाहते हैं और परवाह नहीं करते हैं। यदि आप विशिष्ट पंक्तियों को चाहते हैं, तो सबसे हालिया रिकॉर्ड की तरह, आपको वशीकरण के उत्तर की तरह, एक उप-प्रकार में सॉर्ट करने की आवश्यकता है। ओरेकल क्रमबद्ध होने से पहले ही पंक्तिबद्ध कार्य करता है।
स्कॉट बेली

4
@ सॉट यूप। वह सही है। और पैट्रिक, अच्छा बिंदु मुझे लगता है कि उस पर वाक्य रचना गलत है। यह वास्तव में एक ओवर (dense_rank () अंतिम ...) होना चाहिए
mcpeterson

2
पहले और दूसरे उदाहरण के बीच अंतर यह है कि पहले एक पंक्ति का चयन करता है (कोई भी पंक्ति, बिना किसी आदेश के)। दूसरा उदाहरण पहली पंक्ति का मूल्य प्राप्त करता है, एक ऑर्डर इनर क्वेरी के बिना (नीचे दिए गए उदाहरणों के अनुसार)।
जूल्सलेट

3
सिंटैक्स सही नहीं है: MyTbl से अधिकतम (fname) ओवर (रैंक () ऑर्डर by some_factor)
स्टीफन

1
@jclozano "ओरेकल की एक बहुत अच्छी तरह से ज्ञात कार्यक्षमता नहीं है" - सम्मान के साथ, मैं अलग होने की भीख मांगता हूं। यह मायने रखता है क्योंकि "अच्छी तरह से ज्ञात कार्यक्षमता" अस्पष्टता का संकेत नहीं देती है और इसलिए सुझाव दे सकती है कि हमें इसका उपयोग करने से बचना चाहिए। यह अस्पष्ट नहीं है, और इसके उपयोग से बचा नहीं जाना चाहिए।
सिपाही

166
SELECT *
  FROM (SELECT * FROM MyTbl ORDER BY Fname )
 WHERE ROWNUM = 1;

8
यह उत्तर सही ढंग से TOP पंक्ति को प्राप्त होता है (डाउनलोड पर प्रतिबंधित करने से पहले परिणाम बताता है)।
जूल्सलेट

यह उत्तर सटीक अनुवाद नहीं है - मूल क्वेरी में ORDER BY नहीं है, और न ही यह तालिका के सभी कॉलम लौटाता है।
OMG पॉनीज

मैं सही (नीचे देखें) खड़ा हूं। समय पूरा होने पर वोट स्विच करेंगे।
JulesLt

7
@OMGPonies हाँ। लेकिन शायद यह कि ज्यादातर लोग वास्तव में क्या चाहते हैं जो इस पृष्ठ पर अपनी समस्या को देखते हुए आते हैं
निमशिम्प्सकी

4
यह सुनिश्चित करने के लिए इस धागे में जीतने का जवाब होना चाहिए। मैं एक नोट जोड़ सकते हैं कि के लिए top Xएक करने के लिए इसे बदल सकते हैंWHERE ROWNUM <= X
SomethingSomething

31

साथ ओरेकल 12C (जून 2013), आप निम्नलिखित की तरह उपयोग कर सकते हैं।

SELECT * FROM   MYTABLE
--ORDER BY COLUMNNAME -OPTIONAL          
OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY

6
दिलचस्प आदेश, मैं यहां 12c का उपयोग कर रहा हूं और OFFSET 0 ROWSजाहिरा तौर पर आवश्यक नहीं है, आप उपयोग कर सकते हैं FETCH NEXT 1 ROWS ONLYया यहां तक ​​कि FETCH FIRST ROW ONLY, आदेश महत्वपूर्ण है या यह सिर्फ एक का उपयोग करने के बराबर होगा WHERE rownum = 1। मैंने इसे एक OUTER APPLY इंस्ट्रक्शन में भी आज़माया है और यह Ms-SQL के टॉप फंक्शन की तरह काम करता है।
राफेल मर्लिन

आप सही हैं @ राफेलमेर्लिन। आपके पोस्ट के बाद मैंने माना कि OFFSET 0 ROWS आवश्यक नहीं है। शीर्ष25 और शीर्ष वाई के बीच डेटा को पुनर्प्राप्त करते समय यह उपयोगी होगा
एमएसके

1
अधिक उदाहरण: oracle-base.com/articles/12c/…
FixFaier

अब तक बहुत अच्छा है, एक महत्वपूर्ण लापता बिंदु के साथ जो है TIESयह उन मामलों के लिए देखें , जब संस्करण के लिए संबंध होते हैं 12c +और12c -
बारब्रोस ज़हान

10

आप उप-क्वेरी में ROW_NUMBER()एक ORDER BYक्लॉज के साथ उपयोग कर सकते हैं और इस कॉलम को प्रतिस्थापन में बदल सकते हैं TOP N। इसे चरण-दर-चरण समझाया जा सकता है।

नीचे दी गई तालिका देखें जिसमें दो कॉलम हैं NAMEऔर DT_CREATED

यहां छवि विवरण दर्ज करें

यदि आपको इसकी परवाह किए बिना केवल पहली दो तारीखें लेने की आवश्यकता है NAME, तो आप नीचे दिए गए क्वेरी का उपयोग कर सकते हैं। तर्क क्वेरी के अंदर लिखा गया है

-- The number of records can be specified in WHERE clause
SELECT RNO,NAME,DT_CREATED
FROM
(
    -- Generates numbers in a column in sequence in the order of date
    SELECT ROW_NUMBER() OVER (ORDER BY DT_CREATED) AS RNO,
    NAME,DT_CREATED
    FROM DEMOTOP
)TAB
WHERE RNO<3;

परिणाम

यहां छवि विवरण दर्ज करें

कुछ स्थितियों में, हमें TOP Nप्रत्येक से संबंधित परिणामों का चयन करना होगा NAME। ऐसे मामले में हम उप-क्वेरी में PARTITION BYएक ORDER BYखंड के साथ उपयोग कर सकते हैं । नीचे दिए गए प्रश्न का संदर्भ लें।

-- The number of records can be specified in WHERE clause
SELECT RNO,NAME,DT_CREATED
FROM
(
  --Generates numbers in a column in sequence in the order of date for each NAME
    SELECT ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY DT_CREATED) AS RNO,
    NAME,DT_CREATED
    FROM DEMOTOP
)TAB
WHERE RNO<3;

परिणाम

यहां छवि विवरण दर्ज करें


1
ROW_NUMBER () ... का उपयोग करना विषय के उत्तर की तुलना में अधिक सही समाधान है। इस समाधान के साथ एक समस्या (और अधिकतम (फ़ील्ड) संस्करण के साथ भी) कि आप अपडेट के लिए "चयन ... (ROW_NUMBER () ...) जैसी चीज़ों को नहीं कर सकते हैं ?"
अलेक्सो पो।

और यह कभी-कभी PL / SQL में बहुत महत्वपूर्ण है (क्षमा करें, पिछली टिप्पणी को 5 मिनट की सीमा में संपादित करने में विफल रहा)।
अलेक्सो पो।

ऐसे मामले में हम बाहरी भाग के रूप में सीटीई का उपयोग कर सकते हैं। सही? @ एलेक्सो पो।
सारथ अवनवु

मुझे लगता है कि मैं आपको नहीं समझता। जब ROWID को "आसानी से" Oracle द्वारा संरक्षित किया जाता है, तो अपडेट क्लॉज का उपयोग किया जा सकता है। इसलिए समूहीकरण (और विश्लेषणात्मक क्लॉज़ उपयोग के कारण समूहीकृत करना) वास्तविक ROWID को छुपाता है और पंक्तियों को लॉक नहीं किया जा सकता है। और दूसरा, सीटीई ( with (select ... ) as क्लॉज) इस समस्या के लिए कुछ भी नहीं बदलता है, सीटीई सिर्फ प्रश्नों को पढ़ने और समर्थन करने के उद्देश्य से है। सही? @ सारथ अवानवु
पो।

खुद पर ध्यान दें। ROWID के साथ समस्या वास्तव में RNO <3 स्थिति के कारण विशेष रूप से होती है, इस मामले में RNO का मान ROWID से जुड़ा नहीं है, यही कारण है कि Oracle पंक्तियों को लॉक नहीं कर सकता है।
अलेक्सो पो।

9

आप कुछ ऐसा कर सकते हैं

    SELECT *
      FROM (SELECT Fname FROM MyTbl ORDER BY Fname )
 WHERE rownum = 1;

आप विश्लेषणात्मक कार्यों RANK और / या DENSE_RANK का भी उपयोग कर सकते हैं , लेकिन ROWNUM शायद सबसे आसान है।


1
क्या आप रैंक आदि के कुछ उदाहरणों के साथ मदद कर सकते हैं
ब्रेकफ्रीहग


5

उपयोग:

SELECT x.*
  FROM (SELECT fname 
          FROM MyTbl) x
 WHERE ROWNUM = 1

यदि Oracle9i + का उपयोग कर रहे हैं, तो आप ROW_NUMBER () जैसे विश्लेषणात्मक कार्यों का उपयोग करके देख सकते हैं, लेकिन वे ROWNUM के रूप में भी प्रदर्शन नहीं करेंगे


1
अच्छा जवाब है, लेकिन एक छोटे टाइपो होता है। जहाँ आप Oracle9i + कहते हैं कि 8i नहीं होना चाहिए? download-west.oracle.com/docs/cd/A87860_01/doc/server.817/…
Ian बढ़ई

@carpenteri: सच है, एनालिटिक्स 8i में उपलब्ध थे - का विवरण याद नहीं कर सकते हैं, लेकिन एनालिटिक्स वास्तव में 9i तक जनता के लिए उपलब्ध नहीं थे।
OMG पॉनीज

छोटी टिप्पणी - नीचे दिए गए वश के उत्तर में आंतरिक क्वेरी पर एक ORDER BY शामिल है जो महत्वपूर्ण है यदि आप 'पहले' के बजाय fname का शीर्ष मान चाहते हैं (जो कुछ भी हो सकता है, सबसे अधिक संभावना पहली पंक्ति सम्मिलित की गई है)। एक संपादन के लायक हो सकता है?
जूल्सलेट

@JulesLt: ओपी द्वारा प्रदान की जाने वाली क्वेरी में ORDER BY शामिल नहीं है, इसलिए यह Oracle सिंटैक्स के लिए प्रतिनिधित्व और सटीक अनुवाद है।
OMG पॉन्जी

SQL सर्वर टॉप सिंटैक्स की मेरी गलतफहमी (गलती से यह अनुमान लगाया गया कि यह RANK में FIRST के समान था, ROWNUM नहीं)। वोट दिया।
JulesLt

3

तालिका से पहली पंक्ति चुनने के लिए और तालिका से एक पंक्ति चुनने के लिए दो अलग-अलग कार्य हैं और एक अलग क्वेरी की आवश्यकता है। ऐसा करने के कई संभावित तरीके हैं। उनमें से चार हैं:

प्रथम

select  max(Fname) from MyTbl;

दूसरा

select  min(Fname) from MyTbl;

तीसरा

select  Fname from MyTbl  where rownum = 1;

चौथा

select  max(Fname) from MyTbl where rowid=(select  max(rowid) from MyTbl)

3

मेरे पास एक ही मुद्दा था, और मैं इस समाधान के साथ इसे ठीक कर सकता हूं:

select a.*, rownum 
from (select Fname from MyTbl order by Fname DESC) a
where
rownum = 1

शीर्ष पर पहला मान रखने से पहले आप अपना परिणाम ऑर्डर कर सकते हैं।

सौभाग्य

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