tags:

views:

92

answers:

4

How do you do LIMIT in DB2 for iSeries?

I have a table with more than 50,000 records and I want to return records 0 to 10,000, and records 10,000 to 20,000.

I know in SQL you write LIMIT 0,10000 at the end of the query for 0 to 10,000 and LIMIT 10000,10000 at the end of the query for 10000 to 20,000

So, how is this done in DB2? Whats the code and syntax? (full query example is appreciated)

+2  A: 

Using 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;

To get ranges, you'd have to use ROW_NUMBER() and use that within the WHERE clause: (stolen from here: 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;
Joe
yeah, I found this too, hehe. I was editing the question at the same time to indicate that I want middle rows too.
elcool
You have to do something like this with ROW_NUMBER: http://www.justskins.com/forums/db2-select-how-to-123209.html
Joe
`ROW_NUMBER` is not a valid keyword. But thx for the link, it gave me an idea and it works.
elcool
+1  A: 

Developed this method:

You NEED a table that has an unique value that can be ordered.

If you want rows 10,000 to 25,000 and your Table has 40,000 rows, first you need to get the starting point and total rows:

int start = 40000 - 10000;

int total = 25000 - 10000;

And then pass these by code to the query:

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
elcool
A: 

You should also consider the OPTIMIZE FOR n ROWS clause. More details on all of this in the DB2 LUW documentation in the Guidelines for restricting SELECT statements topic:

  • The OPTIMIZE FOR clause declares the intent to retrieve only a subset of the result or to give priority to retrieving only the first few rows. The optimizer can then choose access plans that minimize the response time for retrieving the first few rows.
David Sky
A: 

ROW_NUMBER() was only implemented in iSeries DB2 V5R4. For previous versions try using RRN() which is similar.

Paul Morgan
RRN() is completely different than row_number().
Brandon Peterson
did not work for me. Sytanx error.
elcool
Try RRN(filename) which will give the physical relative record number of the row. RRN won't be sequential and can skip numbers if rows have been deleted. RRN also won't be sequential by key but will be sequential based on addition if no deletes have occured. In any case RRN will be unique for a row and can be used to select subsets of the table.
Paul Morgan