2013-02-26 191 views
84

मुझे अपने उत्पाद को संगत करने के लिए SQL सर्वर से ओरेकल तक संग्रहीत प्रक्रियाओं को परिवर्तित करने में कठिनाई हो रही है।ओरेकल ऑर्डर BY और ROWNUM का सही तरीके से उपयोग कैसे करें?

मैं प्रश्नों जो कुछ तालिकाओं के सबसे हाल ही में रिकॉर्ड देता है, एक टाइमस्टैम्प के आधार पर है:

एसक्यूएल सर्वर:

SELECT TOP 1 * 
FROM RACEWAY_INPUT_LABO 
ORDER BY t_stamp DESC 

=> कि मुझे हाल ही में रिकॉर्ड रिटर्न

लेकिन ओरेकल:

SELECT * 
FROM raceway_input_labo 
WHERE rownum <= 1 
ORDER BY t_stamp DESC 

=>ORDER BY कथन के बावजूद, यह मुझे सबसे पुराना रिकॉर्ड (शायद सूचकांक के आधार पर) देता है!

SELECT * 
FROM 
    (SELECT * 
    FROM raceway_input_labo 
    ORDER BY t_stamp DESC) 
WHERE rownum <= 1 

और यह काम करता है:

मैं ओरेकल क्वेरी इस तरह से मेरी आवश्यकताओं से मेल करने समझाया। लेकिन यह मेरे लिए एक भयानक हैक की तरह लगता है, खासकर यदि मेरे पास शामिल तालिकाओं में बहुत सारे रिकॉर्ड हैं।

इसे प्राप्त करने का सबसे अच्छा तरीका क्या है?

+0

(http://www.oracle.com/technetwork/issue-archive/2006/06-sep/o56asktom-086197 [ROWNUM और सीमित परिणाम पर]। एचटीएमएल) –

+4

आपने अपनी अंतिम क्वेरी में क्या किया है वह सही है। आप रिकॉर्ड्स की ऑर्डर की गई सूची की पहली पंक्ति का चयन करते हैं। बस क्वेरी encapsulation। – araknoid

+1

यह मैनुअल में स्पष्ट रूप से प्रलेखित है: http://docs.oracle.com/cd/E11882_01/server.112/e26088/pseudocolumns009.htm#i1006297 –

उत्तर

84

where बयानorder by से पहले मार डाला जाता है। तो, आपकी वांछित क्वेरी कह रही है "पहली पंक्ति लें और फिर इसेt_stampdesc" द्वारा ऑर्डर करें। और यह वही नहीं है जो आप चाहते हैं।

ओरेकल में ऐसा करने के लिए सबक्वायरी विधि उचित विधि है।

आप एक संस्करण है कि दोनों सर्वर में काम करता है चाहते हैं, तो आप उपयोग कर सकते हैं:

select ril.* 
from (select ril.*, row_number() over (order by t_stamp desc) as seqnum 
     from raceway_input_labo ril 
    ) ril 
where seqnum = 1 

बाहरी * "1" वापस आ जाएगी अंतिम स्तंभ में। इससे बचने के लिए आपको व्यक्तिगत रूप से कॉलम सूचीबद्ध करना होगा।

19

इसके बजाय ROW_NUMBER() का उपयोग करें। ROWNUM एक छद्म चिह्न है और ROW_NUMBER() एक समारोह है। आप उन दोनों के बीच अंतर के बारे में पढ़ सकते हैं और नीचे प्रश्नों के उत्पादन में अंतर देख सकते हैं: ऊपर एक टिप्पणी में इस के साथ डिजाइन मुद्दों की

SELECT * FROM (SELECT rownum, deptno, ename 
      FROM scott.emp 
     ORDER BY deptno 
     ) 
WHERE rownum <= 3 
/

ROWNUM DEPTNO ENAME 
--------------------------- 
7  10 CLARK 
14  10 MILLER 
9  10 KING 


SELECT * FROM 
(
    SELECT deptno, ename 
     , ROW_NUMBER() OVER (ORDER BY deptno) rno 
    FROM scott.emp 
ORDER BY deptno 
) 
WHERE rno <= 3 
/

DEPTNO ENAME RNO 
------------------------- 
10 CLARK  1 
10 MILLER  2 
10 KING   3 
+2

'ROWNUM'' ROW_NUMBER() 'से तेज हो सकता है ताकि किसी को एक का उपयोग करना चाहिए या नहीं दूसरे पर कई कारकों पर निर्भर करता है। –

0

प्रलेखित जोड़े। ओरेकल में लघु कहानी, आपको परिणामों को मैन्युअल रूप से सीमित करने की आवश्यकता होती है जब आपके पास समान कॉलम नाम वाली बड़ी टेबल और/या टेबल होते हैं (और आप उन्हें स्पष्ट रूप से टाइप नहीं करना चाहते हैं और उन सभी का नाम बदलना चाहते हैं)। आसान समाधान अपने ब्रेकपॉइंट को समझना और आपकी क्वेरी में सीमित करना है। या यदि आप विवादित कॉलम नाम बाधा नहीं रखते हैं तो आप आंतरिक क्वेरी में भी ऐसा कर सकते हैं। ईजी।

WHERE 
m_api_log.created_date BETWEEN TO_DATE ('10/23/2015 05:00', 'MM/DD/YYYY HH24:MI') AND TO_DATE ('10/30/2015 23:59', 'MM/DD/YYYY HH24:MI') 

परिणाम को काफी हद तक कम कर देगा। फिर आप पंक्तियों को सीमित करने के लिए बाहरी क्वेरी द्वारा ऑर्डर कर सकते हैं या यहां तक ​​कि कर सकते हैं।

इसके अलावा, मुझे लगता है कि TOAD में पंक्तियों को सीमित करने की सुविधा है; लेकिन, सुनिश्चित नहीं है कि ओरेकल पर वास्तविक क्वेरी के भीतर सीमित है।निश्चित नहीं।

-2

बस निम्नलिखित

select * 
from (select t.* 
     from raceway_input_labo ril 
     order by t_stamp desc 
    )  
where rownum = 1 
+0

देखता है कि यह दो बार डाउनवॉट किया गया था। मुझे पता है कि यह समाधान अच्छी तरह से काम नहीं करता है, लेकिन मुझे नहीं पता क्यों। क्या कोई कृपया बताएगा क्यों? धन्यवाद। – JasonGabler

+1

@ जेसन गैबलर 'टी'' ril' होना चाहिए। उन्होंने उस टाइपो को 3 साल बाद स्वीकृत उत्तर से कॉपी किया। इसके अलावा यह कोड हमेशा प्रश्न में रहा है। "इस तरह" की कोई व्याख्या नहीं है, इसलिए यह कुछ भी समझा नहीं है। – philipxy

0

तरह ROWNUM का उपयोग एक वैकल्पिक मैं इस प्रयोग के मामले में सुझाव है कि मैक्स (t_stamp) का उपयोग करने के लिए नवीनतम पंक्ति पाने के लिए ... जैसे है

select t.* from raceway_input_labo t 
where t.t_stamp = (select max(t_stamp) from raceway_input_labo) 
limit 1 

मेरे कोडिंग पैटर्न वरीयता (शायद) - विश्वसनीय, आम तौर पर प्रदर्शन करती है या एक हल कर सूची से 1 पंक्ति का चयन करने की कोशिश कर की तुलना में बेहतर - यह भी मंशा अधिक स्पष्ट रूप से पठनीय है।
आशा इस मदद करता है ...

SQLer

+0

ओरेकल में कोई सीमा नहीं है। आप सवाल पूछ रहे हैं। – philipxy