<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.amar.com/index.php?action=history&amp;feed=atom&amp;title=Notepad%3AOracle_Pagination</id>
	<title>Notepad:Oracle Pagination - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.amar.com/index.php?action=history&amp;feed=atom&amp;title=Notepad%3AOracle_Pagination"/>
	<link rel="alternate" type="text/html" href="https://wiki.amar.com/index.php?title=Notepad:Oracle_Pagination&amp;action=history"/>
	<updated>2026-04-08T01:49:24Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.44.2</generator>
	<entry>
		<id>https://wiki.amar.com/index.php?title=Notepad:Oracle_Pagination&amp;diff=388&amp;oldid=prev</id>
		<title>67.52.184.2: Oracle Pagination</title>
		<link rel="alternate" type="text/html" href="https://wiki.amar.com/index.php?title=Notepad:Oracle_Pagination&amp;diff=388&amp;oldid=prev"/>
		<updated>2007-06-25T23:30:44Z</updated>

		<summary type="html">&lt;p&gt;Oracle Pagination&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== The Problem ==&lt;br /&gt;
We need to be able to paginate result sets without burdening the servers with too many data and unnecessary sorts. It is also best to order the data straight from the database, which is the natural and best tool for the job.&lt;br /&gt;
&lt;br /&gt;
== The Solution ==&lt;br /&gt;
Oracle has a &amp;lt;code&amp;gt;PSEUDO-COLUMN&amp;lt;/code&amp;gt; field called &amp;lt;code&amp;gt;ROWNUM&amp;lt;/code&amp;gt; that can assist in pagination or retrieved data. Unfortunately, this field is set as data is retrieved from a query, &amp;lt;em&amp;gt;BEFORE&amp;lt;/em&amp;gt; any ordering. In order to work around this limitation, we need to encapsulate the query in 2 sub-selects:&lt;br /&gt;
&lt;br /&gt;
=== Original Query ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 SELECT u.* &lt;br /&gt;
   FROM &amp;quot;User&amp;quot; u &lt;br /&gt;
   WHERE emailaddress LIKE &amp;#039;%foldera%&amp;#039;&lt;br /&gt;
   order by lname, fname&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Optimized Query ===&lt;br /&gt;
From : [http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html On ROWNUM and Limiting Results]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT * &lt;br /&gt;
  FROM ( SELECT /*+ FIRST_ROWS(n) */ &lt;br /&gt;
  ROWNUM AS display_rows, inside.*&lt;br /&gt;
      FROM ( &lt;br /&gt;
      SELECT u.* &lt;br /&gt;
      FROM &amp;quot;User&amp;quot; u &lt;br /&gt;
      WHERE emailaddress LIKE &amp;#039;%foldera%&amp;#039; &lt;br /&gt;
      ORDER BY lname, fname  &lt;br /&gt;
      ) inside&lt;br /&gt;
      WHERE ROWNUM &amp;lt;= 10&lt;br /&gt;
  ) outside &lt;br /&gt;
WHERE display_rows  &amp;gt;= 5;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This query will only get the first &amp;lt;code&amp;gt;LAST_RECORD&amp;lt;/code&amp;gt; records and save a lot of time and memory for the first pages of a query. Note that &amp;lt;code&amp;gt;FIRST_RECORD&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;LAST_RECORD&amp;lt;/code&amp;gt; are reversed.&lt;br /&gt;
&lt;br /&gt;
=== Unoptimized Query ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT * &lt;br /&gt;
FROM ( &lt;br /&gt;
   SELECT ROWNUM AS display_rows,&lt;br /&gt;
      inside.* &lt;br /&gt;
   FROM ( &lt;br /&gt;
      SELECT u.* &lt;br /&gt;
      FROM &amp;quot;User&amp;quot; u &lt;br /&gt;
      WHERE emailaddress LIKE &amp;#039;%foldera%&amp;#039; &lt;br /&gt;
      ORDER BY lname, fname &lt;br /&gt;
   ) inside &lt;br /&gt;
) outside &lt;br /&gt;
WHERE display_rows &amp;gt;= 5 AND display_rows &amp;lt;= 10;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Generalized Form ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT * &lt;br /&gt;
  FROM ( &lt;br /&gt;
    SELECT /*+ FIRST_ROWS(n) */ &lt;br /&gt;
      ROWNUM AS display_rows, inside.*&lt;br /&gt;
      FROM ( &lt;br /&gt;
         &amp;lt;... original query with ordering here ...&amp;gt; &lt;br /&gt;
      ) inside&lt;br /&gt;
      WHERE ROWNUM &amp;lt;= :LAST_RECORD&lt;br /&gt;
  ) outside &lt;br /&gt;
WHERE display_rows  &amp;gt;= :FIRST_RECORD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Specialized Form ===&lt;br /&gt;
If the original query DOES NOT contain any sorting or ordering, we can skip one level of inner subselect:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT * &lt;br /&gt;
   FROM ( &lt;br /&gt;
      SELECT ROWNUM AS display_rows, u.* &lt;br /&gt;
      FROM &amp;quot;User&amp;quot; u &lt;br /&gt;
      WHERE emailaddress LIKE &amp;#039;%foldera%&amp;#039;&lt;br /&gt;
   ) inside &lt;br /&gt;
WHERE display_rows &amp;gt;= 5 AND display_rows &amp;lt;= 10;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unfortunately, this requires adding a field to the original inner query.&lt;br /&gt;
&lt;br /&gt;
== Strategy ==&lt;br /&gt;
The strategy is then have a all paged queries wrapped by the proper construct. Since all ou queries are now external strings, this is a trivial task. &lt;br /&gt;
&lt;br /&gt;
The first algorithm that comes to mind is:&lt;br /&gt;
 FIRST_RECORD := (PAGE_NO - 1) * RECORDS_PER_PAGE + 1;&lt;br /&gt;
 LAST_RECORD := PAGE_NO * RECORDS_PER_PAGE;&lt;br /&gt;
&lt;br /&gt;
It is a good idea to have Javascript determine the &amp;lt;code&amp;gt;RECORDS_PER_PAGE&amp;lt;/code&amp;gt; info (and have it recalculated by an &amp;lt;code&amp;gt;onresize=&amp;quot;recalcsize();&amp;quot;&amp;lt;/code&amp;gt; construct and have AJAX calls pass this info to the calling &amp;lt;code&amp;gt;GET...&amp;lt;/code&amp;gt; routine&lt;br /&gt;
&lt;br /&gt;
== Discussion ==&lt;br /&gt;
* Does this get the full data set and simply filters what we need&lt;br /&gt;
yes&lt;br /&gt;
* Isn&amp;#039;t this wasteful?&lt;br /&gt;
The data has to be fully analyzed to get this. Whether on the DB or web server or client machine. The best place for this is on the server where we get the most optimized engine for manipulating sorted data.&lt;br /&gt;
* Can we generalize the sorting without rewriting the query?&lt;br /&gt;
I&amp;#039;ll have to look at it more ... keep in touch !&lt;/div&gt;</summary>
		<author><name>67.52.184.2</name></author>
	</entry>
</feed>