Quantcast
Channel: How do I limit the number of rows returned by an Oracle query after ordering? - Stack Overflow
Viewing all articles
Browse latest Browse all 17

Answer by Lukasz Szozda for How do I limit the number of rows returned by an Oracle query after ordering?

$
0
0

As an extension of accepted answer Oracle internally uses ROW_NUMBER/RANK functions. OFFSET FETCH syntax is a syntax sugar.

It could be observed by using DBMS_UTILITY.EXPAND_SQL_TEXT procedure:

Preparing sample:

CREATE TABLE rownum_order_test (  val  NUMBER);INSERT ALL  INTO rownum_order_testSELECT levelFROM   dualCONNECT BY level <= 10;COMMIT;

Query:

SELECT valFROM   rownum_order_testORDER BY val DESCFETCH FIRST 5 ROWS ONLY;

is regular:

SELECT "A1"."VAL""VAL"FROM  (SELECT "A2"."VAL""VAL","A2"."VAL""rowlimit_$_0",               ROW_NUMBER() OVER ( ORDER BY "A2"."VAL" DESC ) "rowlimit_$$_rownumber"      FROM "ROWNUM_ORDER_TEST""A2") "A1"WHERE "A1"."rowlimit_$$_rownumber"<=5 ORDER BY "A1"."rowlimit_$_0" DESC;

db<>fiddle demo

Fetching expanded SQL text:

declare  x VARCHAR2(1000);begin dbms_utility.expand_sql_text(        input_sql_text => '          SELECT val          FROM   rownum_order_test          ORDER BY val DESC          FETCH FIRST 5 ROWS ONLY',        output_sql_text => x);  dbms_output.put_line(x);end;/

WITH TIES is expanded as RANK:

declare  x VARCHAR2(1000);begin dbms_utility.expand_sql_text(        input_sql_text => '          SELECT val          FROM   rownum_order_test          ORDER BY val DESC          FETCH FIRST 5 ROWS WITH TIES',        output_sql_text => x);  dbms_output.put_line(x);end;/SELECT "A1"."VAL""VAL"FROM  (SELECT "A2"."VAL""VAL","A2"."VAL""rowlimit_$_0",              RANK() OVER ( ORDER BY "A2"."VAL" DESC ) "rowlimit_$$_rank"       FROM "ROWNUM_ORDER_TEST""A2") "A1"WHERE "A1"."rowlimit_$$_rank"<=5 ORDER BY "A1"."rowlimit_$_0" DESC

and offset:

declare  x VARCHAR2(1000);begin dbms_utility.expand_sql_text(        input_sql_text => '          SELECT valFROM   rownum_order_testORDER BY valOFFSET 4 ROWS FETCH NEXT 4 ROWS ONLY',        output_sql_text => x);  dbms_output.put_line(x);end;/SELECT "A1"."VAL""VAL"FROM  (SELECT "A2"."VAL""VAL","A2"."VAL""rowlimit_$_0",             ROW_NUMBER() OVER ( ORDER BY "A2"."VAL") "rowlimit_$$_rownumber"       FROM "ROWNUM_ORDER_TEST""A2") "A1"       WHERE "A1"."rowlimit_$$_rownumber"<=CASE  WHEN (4>=0) THEN FLOOR(TO_NUMBER(4))              ELSE 0 END +4 AND "A1"."rowlimit_$$_rownumber">4 ORDER BY "A1"."rowlimit_$_0"

Viewing all articles
Browse latest Browse all 17

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>