sql - ऑर्डर करने के बाद ओरेकल क्वेरी द्वारा लौटाई गई पंक्तियों की संख्या को मैं कैसे सीमित करूं?




oracle pagination limit (12)

क्या Oracle क्वेरी व्यवहार करने का कोई तरीका है जैसे इसमें एक MySQL limit खंड है?

MySQL , मैं यह कर सकता हूं:

select * 
from sometable
order by name
limit 20,10

21 वीं से 30 वीं पंक्तियों को प्राप्त करने के लिए (पहले 20 छोड़ें, अगले 10 दें)। order by बाद पंक्तियों का चयन order by , इसलिए यह वास्तव में 20 वें नाम पर वर्णानुक्रम से शुरू होता है।

Oracle , लोगों का उल्लेख केवल एक चीज है जो rownum छद्म-कॉलम है, लेकिन इसका order by करने से पहले मूल्यांकन किया order by , जिसका अर्थ यह है:

select * 
from sometable
where rownum <= 10
order by name

नाम से आदेशित दस पंक्तियों का यादृच्छिक सेट वापस कर देगा, जो आम तौर पर मैं नहीं चाहता हूं। यह ऑफसेट निर्दिष्ट करने की अनुमति भी नहीं देता है।


Answers

select * FROM (SELECT 
   ROW_NUMBER() OVER (ORDER BY sal desc),* AS ROWID, 
 FROM EMP ) EMP  where ROWID=5

अधिक मूल्यों को पता लगाना

select * FROM (SELECT 
       ROW_NUMBER() OVER (ORDER BY sal desc),* AS ROWID, 
     FROM EMP ) EMP  where ROWID>5

कम मूल्यों को पता लगाना

select * FROM (SELECT 
       ROW_NUMBER() OVER (ORDER BY sal desc),* AS ROWID, 
     FROM EMP ) EMP  where ROWID=5

मैंने निम्नलिखित दृष्टिकोणों के लिए कुछ प्रदर्शन परीक्षण किया:

Asktom

select * from (
  select a.*, ROWNUM rnum from (
    <select statement with order by clause>
  ) a where rownum <= MAX_ROW
) where rnum >= MIN_ROW

विश्लेषणात्मक

select * from (
  <select statement with order by clause>
) where myrow between MIN_ROW and MAX_ROW

लघु वैकल्पिक

select * from (
  select statement, rownum as RN with order by clause
) where a.rn >= MIN_ROW and a.rn <= MAX_ROW

परिणाम

तालिका में 10 मिलियन रिकॉर्ड थे, क्रमशः एक अनदेखा डेटाटाइम पंक्ति पर था:

  • समझाओ योजना ने सभी तीन चयनों (323168) के लिए समान मूल्य दिखाया
  • लेकिन विजेता AskTom है (पीछे के पीछे विश्लेषणात्मक के साथ)

पहली 10 पंक्तियों का चयन करना:

  • AskTom: 28-30 सेकंड
  • विश्लेषणात्मक: 33-37 सेकंड
  • लघु विकल्प: 110-140 सेकंड

पंक्तियों का चयन 100,000 और 100,010:

  • AskTom: 60 सेकंड्स
  • विश्लेषणात्मक: 100 सेकंड

9,000,000 और 9, 000, 2010 के बीच पंक्तियों का चयन करना:

  • AskTom: 130 सेकंड्स
  • विश्लेषणात्मक: 150 सेकंड

आदेश के साथ अंकन प्रश्न ओरेकल में वास्तव में मुश्किल हैं।

ओरेकल एक ROWNUM छद्म प्रोटोकॉल प्रदान करता है जो उस क्रम को इंगित करता है जिसमें डेटाबेस तालिका से पंक्ति का चयन करता है या शामिल दृश्यों के सेट का चयन करता है।

ROWNUM एक छद्म चक्र है जो कई लोगों को परेशानी में डाल देता है। एक ROWNUM मान स्थायी रूप से एक पंक्ति को असाइन नहीं किया जाता है (यह एक आम गलतफहमी है)। जब यह ROWNUM मान वास्तव में असाइन किया जाता है तो यह भ्रमित हो सकता है। एक ROWNUM मान को पंक्ति के लिए निर्दिष्ट किया जाता है जब यह क्वेरी के फ़िल्टर पूर्वानुमान को पास करता है लेकिन क्वेरी एकत्रीकरण या सॉर्टिंग से पहले

और भी, ROWNUM मान को असाइन किए जाने के बाद ही बढ़ाया जाता है।

यही कारण है कि फॉलोइन क्वेरी कोई पंक्ति नहीं देता है:

 select * 
 from (select *
       from some_table
       order by some_column)
 where ROWNUM <= 4 and ROWNUM > 1; 

क्वेरी परिणाम की पहली पंक्ति ROWNUM> 1 predicate को पास नहीं करती है, इसलिए ROWNUM 2 तक बढ़ता नहीं है। इस कारण से, कोई ROWNUM मान 1 से अधिक नहीं हो जाता है, परिणामस्वरूप, क्वेरी कोई पंक्ति नहीं देती है।

सही ढंग से परिभाषित क्वेरी इस तरह दिखनी चाहिए:

select *
from (select *, ROWNUM rnum
      from (select *
            from skijump_results
            order by points)
      where ROWNUM <= 4)
where rnum > 1; 

Vertabelo ब्लॉग पर मेरे लेखों में Vertabelo प्रश्नों के बारे में अधिक जानकारी Vertabelo करें:


केवल एक नेस्टेड क्वेरी के साथ एक विश्लेषणात्मक समाधान:

SELECT * FROM
(
   SELECT t.*, Row_Number() OVER (ORDER BY name) MyRow FROM sometable t
) 
WHERE MyRow BETWEEN 10 AND 20;

Rank() को Row_Number() लिए प्रतिस्थापित किया जा सकता है लेकिन यदि आप नाम के लिए डुप्लिकेट मान हैं तो अपेक्षा से अधिक रिकॉर्ड लौटा सकते हैं।


कम चयन कथन। इसके अलावा, कम प्रदर्शन उपभोग। क्रेडिट्स: [email protected]

SELECT *
    FROM   (SELECT t.*,
                   rownum AS rn
            FROM   shhospede t) a
    WHERE  a.rn >= in_first
    AND    a.rn <= in_first;

सुधार के साथ उपरोक्त के समान। काम करता है लेकिन निश्चित रूप से सुंदर नहीं है।

   WITH
    base AS
    (
        select *                   -- get the table
        from sometable
        order by name              -- in the desired order
    ),
    twenty AS
    (
        select *                   -- get the first 30 rows
        from base
        where rownum <= 30
        order by name              -- in the desired order
    )
    select *                       -- then get rows 21 .. 30
    from twenty
    where rownum < 20
    order by name                  -- in the desired order

ईमानदारी से, उपरोक्त उत्तरों का उपयोग करने के लिए बेहतर है।


आप इस तरह के लिए एक सबक्वायरी का उपयोग कर सकते हैं

select *
from  
( select * 
  from emp 
  order by sal desc ) 
where ROWNUM <= 5;

अधिक जानकारी के लिए ओरेकल / AskTom पर ROWNUM विषय और सीमित परिणामों पर भी एक नज़र डालें।

अद्यतन : निम्न और ऊपरी सीमाओं के साथ परिणाम को सीमित करने के लिए चीजों को थोड़ा और अधिक फुलाया जाता है

select * from 
( select a.*, ROWNUM rnum from 
  ( <your_query_goes_here, with order by> ) a 
  where ROWNUM <= :MAX_ROW_TO_FETCH )
where rnum  >= :MIN_ROW_TO_FETCH;

(निर्दिष्ट AskTom- आलेख से कॉपी)

अद्यतन 2 : ओरेकल 12 सी (12.1) से शुरू होने से पंक्तियों को सीमित करने या ऑफसेट पर शुरू करने के लिए एक वाक्यविन्यास उपलब्ध है।

SELECT * 
FROM   sometable
ORDER BY name
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

अधिक उदाहरणों के लिए यह उत्तर देखें। संकेत के लिए Krumia के लिए धन्यवाद।


ओरेकल 12 सी आर 1 (12.1) से शुरू, एक पंक्ति सीमित खंड है । यह परिचित LIMIT वाक्यविन्यास का उपयोग नहीं करता है, लेकिन यह अधिक विकल्पों के साथ बेहतर काम कर सकता है। आप यहां पूर्ण वाक्यविन्यास पा सकते हैं।

मूल प्रश्न का उत्तर देने के लिए, यहां क्वेरी है:

SELECT * 
FROM   sometable
ORDER BY name
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

(पहले ओरेकल संस्करणों के लिए, कृपया इस प्रश्न में अन्य उत्तरों देखें)

उदाहरण:

लिंक रोट को रोकने की उम्मीद में, लिंक किए गए पृष्ठ से निम्नलिखित उदाहरण उद्धृत किए गए थे।

सेट अप

CREATE TABLE rownum_order_test (
  val  NUMBER
);

INSERT ALL
  INTO rownum_order_test
SELECT level
FROM   dual
CONNECT BY level <= 10;

COMMIT;

टेबल में क्या है?

SELECT val
FROM   rownum_order_test
ORDER BY val;

       VAL
----------
         1
         1
         2
         2
         3
         3
         4
         4
         5
         5
         6
         6
         7
         7
         8
         8
         9
         9
        10
        10

20 rows selected.

पहली N पंक्तियां प्राप्त करें

SELECT val
FROM   rownum_order_test
ORDER BY val DESC
FETCH FIRST 5 ROWS ONLY;

       VAL
----------
        10
        10
         9
         9
         8

5 rows selected.

पहली N पंक्तियां प्राप्त करें, अगर N वें पंक्ति संबंध हैं, तो सभी बंधे पंक्तियां प्राप्त करें

SELECT val
FROM   rownum_order_test
ORDER BY val DESC
FETCH FIRST 5 ROWS WITH TIES;

       VAL
----------
        10
        10
         9
         9
         8
         8

6 rows selected.

पंक्तियों का शीर्ष x %

SELECT val
FROM   rownum_order_test
ORDER BY val
FETCH FIRST 20 PERCENT ROWS ONLY;

       VAL
----------
         1
         1
         2
         2

4 rows selected.

ऑफसेट का उपयोग करना, अंकन के लिए बहुत उपयोगी है

SELECT val
FROM   rownum_order_test
ORDER BY val
OFFSET 4 ROWS FETCH NEXT 4 ROWS ONLY;

       VAL
----------
         3
         3
         4
         4

4 rows selected.

आप प्रतिशत के साथ ऑफ़सेट गठबंधन कर सकते हैं

SELECT val
FROM   rownum_order_test
ORDER BY val
OFFSET 4 ROWS FETCH NEXT 20 PERCENT ROWS ONLY;

       VAL
----------
         3
         3
         4
         4

4 rows selected.

मैंने ओरेकल 1z0-047 परीक्षा की तैयारी करना शुरू कर दिया है, जो 12 सी के खिलाफ मान्य है, इसके लिए प्रीपेपिंग करते समय मैं 12 फीट एन्हांसमेंट में आया था जिसे 'फ़ेच प्रथम' कहा जाता है, यह आपको आपकी सुविधा के अनुसार पंक्तियों / सीमा पंक्तियों को लाने में सक्षम बनाता है। इसके साथ कई विकल्प उपलब्ध हैं

- FETCH FIRST n ROWS ONLY
 - OFFSET n ROWS FETCH NEXT N1 ROWS ONLY // leave the n rows and display next N1 rows
 - n % rows via FETCH FIRST N PERCENT ROWS ONLY

उदाहरण:

Select * from XYZ a
order by a.pqr
FETCH FIRST 10 ROWS ONLY

यदि आप ओरेकल 12 सी पर नहीं हैं, तो आप नीचे की तरह शीर्ष एन क्वेरी का उपयोग कर सकते हैं।

SELECT *
 FROM
   ( SELECT rownum rnum
          , a.*
       FROM sometable a 
   ORDER BY name
   )
WHERE rnum BETWEEN 10 AND 20;

आप खंड के साथ इस खंड में भी इसे स्थानांतरित कर सकते हैं

WITH b AS
( SELECT rownum rnum
      , a.* 
   FROM sometable a ORDER BY name
) 
SELECT * FROM b 
WHERE rnum BETWEEN 10 AND 20;

यहां वास्तव में हम एक इनलाइन व्यू बना रहे हैं और राउनम नामकरण के रूप में नामकरण कर रहे हैं। आप फ़िल्टर मानदंड के रूप में मुख्य क्वेरी में rnum का उपयोग कर सकते हैं।


ओरेकल 12 सी पर ( एसक्यूएल संदर्भ में पंक्ति सीमित खंड देखें):

SELECT * 
FROM sometable
ORDER BY name
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

SELECT * FROM tablename WHERE CAST ([my_date_time_var] AS DATE)= '8/5/2015'




sql oracle pagination limit