DB2 के लिए LIMIT के बराबर


91

LIMITISeries के लिए DB2 में आप कैसे करते हैं ?

मेरे पास ५०,००० से अधिक रिकॉर्ड्स के साथ एक तालिका है और मैं ०,००० से १०,०००, और १०,००० से २०,००० के रिकॉर्ड वापस करना चाहता हूं।

मुझे पता है कि SQL में आप LIMIT 0,10000क्वेरी के अंत में 0 से 10,000 तक और LIMIT 10000,10000क्वेरी के अंत में 10000 से 20,000 के लिए लिखते हैं

तो, यह DB2 में कैसे किया जाता है? कोड और वाक्य रचना क्या है? (पूरी क्वेरी उदाहरण की सराहना की है)


ROW_NUMBER () केवल iSeries DB2 V5R4 में लागू किया गया था। पिछले संस्करणों के लिए आरआरएन () का उपयोग करने का प्रयास करें जो समान है।
पॉल मॉर्गन

आरआरएन () पंक्ति_नंबर () से पूरी तरह अलग है।
ब्रैंडन पीटरसन

मेरे लिए काम नहीं किया। Sytanx त्रुटि।
एल्कूल

1
आरआरएन (फ़ाइल नाम) आज़माएं जो पंक्ति के भौतिक सापेक्ष रिकॉर्ड नंबर देगा। आरआरएन अनुक्रमिक नहीं होगा और पंक्तियों को हटाए जाने पर संख्या को छोड़ सकता है। आरआरएन भी कुंजी द्वारा अनुक्रमिक नहीं होगा, लेकिन इसके अलावा अनुक्रमिक होगा यदि कोई विलोपन नहीं हुआ है। किसी भी मामले में आरआरएन एक पंक्ति के लिए अद्वितीय होगा और इसका उपयोग तालिका के सबसेट का चयन करने के लिए किया जा सकता है।
पॉल मॉर्गन

1
डीबी 2 के अनुसार डीबी 2 9.7.2 से सीमा कीवर्ड सहायता प्रदान करने programmingzen.com/2010/06/02/...
लक्ष्मण

जवाबों:


139

का उपयोग कर FETCH FIRST [n] ROWS ONLY:

http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=/com.ibm.db29.doc.perf/db2z_fetchfirstnrows.htm

SELECT LASTNAME, FIRSTNAME, EMPNO, SALARY
  FROM EMP
  ORDER BY SALARY DESC
  FETCH FIRST 20 ROWS ONLY;

सीमाएँ प्राप्त करने के लिए, आपको ROW_NUMBER()(v5r4 से) का उपयोग करना होगा और उस WHEREखंड के भीतर उपयोग करना होगा : (यहाँ से चोरी: http://www.justskins.com/forums/db2-select-how-to-123209.html )

SELECT code, name, address
FROM ( 
  SELECT row_number() OVER ( ORDER BY code ) AS rid, code, name, address
  FROM contacts
  WHERE name LIKE '%Bob%' 
  ) AS t
WHERE t.rid BETWEEN 20 AND 25;

हाँ, मुझे यह भी मिला, हे। मैं एक ही समय में प्रश्न को संपादित कर रहा था ताकि यह इंगित किया जा सके कि मैं मध्य पंक्तियों को भी चाहता हूं।
elcool

2
आपको ROW_NUMBER के साथ ऐसा कुछ करना होगा: justskins.com/forums/db2-select-how-to-123209.html
जो

ROW_NUMBERएक मान्य कीवर्ड नहीं है। लेकिन लिंक के लिए thx, यह मुझे एक विचार दिया और यह काम करता है।
एल्कूल

13

इस विधि का विकास किया:

आपने एक ऐसी तालिका की आवश्यकता है जिसका एक अद्वितीय मूल्य है जिसे आदेश दिया जा सकता है।

यदि आप 10,000 से 25,000 पंक्तियाँ चाहते हैं और आपकी तालिका में 40,000 पंक्तियाँ हैं, तो सबसे पहले आपको प्रारंभिक बिंदु और कुल पंक्तियाँ प्राप्त करनी होंगी:

int start = 40000 - 10000;

int total = 25000 - 10000;

और फिर इन्हें क्वेरी से कोड द्वारा पास करें:

SELECT * FROM 
(SELECT * FROM schema.mytable 
ORDER BY userId DESC fetch first {start} rows only ) AS mini 
ORDER BY mini.userId ASC fetch first {total} rows only

ध्यान दें कि 10000 वीं पंक्ति को परिणाम से बाहर रखा गया है, पहली पंक्ति 10001 वीं है।
ब्लिश

1
दिलचस्प समाधान। मैं H2 परीक्षण डेटाबेस के साथ संगतता के लिए इसका उपयोग करने जा रहा था ... लेकिन, दुख की बात है, यह सेलेक्ट रो_नंबर () OVER (ORDER BY कोड) दृष्टिकोण की तुलना में ~ 30 गुना धीमा काम करता है।
मनुना

9

OFFSET और LIMIT के लिए समर्थन हाल ही में i 7.1 और 7.2 के लिए DB2 में जोड़ा गया था। इस समर्थन को पाने के लिए आपको निम्न DB PTF समूह स्तरों की आवश्यकता है:

  • आईबीएम i 7.2 के लिए SF99702 स्तर 9
  • आईबीएम i 7.1 के लिए SF99701 स्तर 38

अधिक जानकारी के लिए यहां देखें: OFFSET और LIMIT डॉक्यूमेंटेशन , DB2 for i एन्हांसमेंट विकी


7

यहाँ मैं के साथ आया समाधान है:

select FIELD from TABLE where FIELD > LASTVAL order by FIELD fetch first N rows only;

LASTVAL को 0 (या एक टेक्स्ट फ़ील्ड के लिए ') को आरंभीकृत करके, फिर इसे रिकॉर्ड के सबसे हाल के सेट में अंतिम मान पर सेट करें, यह एन रिकॉर्ड्स के क्रम में तालिका के माध्यम से कदम रखेगा।


(मैंने शुरू में सोचा था कि आप तालिका में मूल्य निर्धारित कर रहे हैं, जो समवर्ती प्रणाली पर शानदार रूप से समस्याग्रस्त होगा ) हां, यह उन मामलों में काम करना चाहिए जहां आप तालिका के माध्यम से अनुक्रमिक रीडिंग कर रहे हैं, हालांकि आपको किसी प्रकार की आवश्यकता होगी उस मामले में टाई-ब्रेकर कॉलम जहां कॉलम में Nसमान मूल्यों की संख्या से छोटा है (हालांकि यह ROW_NUMBER()बहुत उपयोग करते समय सच है)। प्रारंभिक मानों को भी ध्यान से चुना जाना चाहिए - 0यदि स्तंभ में ऋणात्मक मान है तो स्पष्ट रूप से समस्याग्रस्त होगा । नल के साथ देखभाल की आवश्यकता होगी। काम नहीं होगा अगर पृष्ठों को छोड़ दिया।
क्लॉकवर्क-म्यूज़ियम

टिप्पणी के लिए धन्यवाद। मुझे लगता है कि एक अंतर्निहित धारणा है कि हम जिस क्षेत्र का उपयोग क्वेरी को नियंत्रित करने के लिए कर रहे हैं वह अद्वितीय और एकतरफा बढ़ रहा है। मैं मानता हूं कि अगर वे धारणाएं नहीं पकड़ती हैं, तो यह तालिका के सभी रिकॉर्डों पर जाने के लिए काम नहीं करेगा। और, निश्चित रूप से, आप सही हैं कि आपको एक LASTVAL के साथ शुरू करना होगा जो समझ में आता है। सामान्य तौर पर, मुझे लगता है कि "TABLE से चयन करें (FIELD)" द्वारा जो भी लौटा है, उसके साथ आप शुरुआत करना चाहेंगे। यदि फ़ील्ड अनुक्रमित है, तो अधिकांश डीबी इंजन पूरे टेबल को क्रमिक रूप से पढ़ने की तुलना में बेहतर करेंगे।
टॉम बैरन

2

@ एल्कूल का समाधान एक स्मार्ट विचार है, लेकिन आपको कुल पंक्तियों की संख्या जानने की आवश्यकता है (जो कि क्वेरी करते समय आप बदल भी सकते हैं!)। इसलिए मैं एक संशोधित संस्करण का प्रस्ताव करता हूं, जिसे दुर्भाग्य से 2 के बजाय 3 उपश्रेणियों की आवश्यकता है:

select * from (
    select * from (
        select * from MYLIB.MYTABLE
        order by MYID asc 
        fetch first {last} rows only 
        ) I 
    order by MYID desc
    fetch first {length} rows only
    ) II
order by MYID asc

{last}मुझे पिछले रिकॉर्ड की पंक्ति संख्या के साथ प्रतिस्थापित किया जाना चाहिए जहां मुझे आवश्यकता है और {length}मुझे आवश्यकतानुसार पंक्तियों की संख्या के साथ प्रतिस्थापित किया जाना चाहिए last row - first row + 1

जैसे अगर मुझे 10 से 25 (पूरी तरह से 16 पंक्तियाँ) पंक्तियाँ {last}चाहिए , तो 25 {length}होगी और 25-10 + 1 = 16 होगी।


मैं उन लोगों को घृणा करता हूं जो किसी अन्य व्यक्ति को अपने प्रश्न का उत्तर देने में समय कम करते हैं।
jp2code

1

आपको n ROWS क्लॉज के लिए OPTIMIZE पर भी विचार करना चाहिए। DB2 LUW दस्तावेज़ीकरण में इन सब पर अधिक विवरण दिशा-निर्देशों का चयन करने के लिए दिशानिर्देशों का चयन करें :

  • खंड के लिए विकल्प परिणाम के केवल सबसेट को पुनः प्राप्त करने या केवल पहले कुछ पंक्तियों को पुनः प्राप्त करने को प्राथमिकता देने के इरादे की घोषणा करता है। आशावादी तब पहुंच योजनाओं को चुन सकता है जो पहले कुछ पंक्तियों को पुनः प्राप्त करने के लिए प्रतिक्रिया समय को कम करते हैं।


0

डीबी 2 टेबल पर कुशलता से पग करने के 2 समाधान हैं:

1 - फंक्शन row_number () और क्लॉज OVER का उपयोग करने वाली तकनीक जिसे किसी अन्य पोस्ट पर प्रस्तुत किया गया है ("Select row_number () OVER (ORDER BY ...)")। कुछ बड़े तालिकाओं पर, मैंने कभी-कभी प्रदर्शनों में गिरावट देखी।

2 - एक स्क्रॉल कर्सर का उपयोग करने वाली तकनीक। कार्यान्वयन उपयोग की गई भाषा पर निर्भर करता है। यह तकनीक बड़ी तालिकाओं पर अधिक मजबूत लगती है।

मैंने PHP में कार्यान्वित 2 तकनीकों को अगले साल एक सेमिनार के दौरान प्रस्तुत किया। इस लिंक पर स्लाइड उपलब्ध है: http://gregphplab.com/serendipity/uploads/slides/DB2_PHP_Best_practices.pdf

क्षमा करें, लेकिन यह दस्तावेज़ केवल फ्रेंच में है।


0

इन उपलब्ध विकल्पों में शामिल हैं: -

DB2 has several strategies to cope with this problem.
You can use the "scrollable cursor" in feature.
In this case you can open a cursor and, instead of re-issuing a query you can FETCH forward and backward.
This works great if your application can hold state since it doesn't require DB2 to rerun the query every time.
You can use the ROW_NUMBER() OLAP function to number rows and then return the subset you want.
This is ANSI SQL 
You can use the ROWNUM pseudo columns which does the same as ROW_NUMBER() but is suitable if you have Oracle skills.
You can use LIMIT and OFFSET if you are more leaning to a mySQL or PostgreSQL dialect.  
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.