DB2 Development
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsDatabasesDB2 Development

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
Stop making mediocre tutorials.The best tutorials are video! Camtasia Studio makes it easy to create engaging, buzz-building screen videos at any size, in any popular format. Download the free trial!
  #1  
Old June 15th, 2004, 11:30 AM
JimmyGosling's Avatar
JimmyGosling JimmyGosling is offline
Back...with an opinion!
Dev Shed Beginner (1000 - 1499 posts)
 
Join Date: Jun 2004
Location: I invented Java
Posts: 1,033 JimmyGosling User rank is Major (30000 - 40000 Reputation Level)JimmyGosling User rank is Major (30000 - 40000 Reputation Level)JimmyGosling User rank is Major (30000 - 40000 Reputation Level)JimmyGosling User rank is Major (30000 - 40000 Reputation Level)JimmyGosling User rank is Major (30000 - 40000 Reputation Level)JimmyGosling User rank is Major (30000 - 40000 Reputation Level)JimmyGosling User rank is Major (30000 - 40000 Reputation Level)JimmyGosling User rank is Major (30000 - 40000 Reputation Level)JimmyGosling User rank is Major (30000 - 40000 Reputation Level)JimmyGosling User rank is Major (30000 - 40000 Reputation Level) 
Time spent in forums: 2 Weeks 1 Day 17 h 2 m 27 sec
Reputation Power: 385
row offset and fetch first * rows

I'm checked around a bit and did not see a similiar post, please correct me if I am wrong. I need to grab a set of rows from my query. I can select those rows by saying FETCH FIRST <however many> ROWS. That works great for the first page. But what happens when I am on page 4 and I need to grab that number of rows with an offset of 4 times that amount.
Can this be done without a stored procedure? That would take way to long to get past the admins here. Can anyone direct me to some resources that might get me started on my way. Can this be done without a cursor?
I'm new to DB2, thanks for your help.

Reply With Quote
  #2  
Old June 15th, 2004, 10:52 PM
fractalvibes fractalvibes is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: Jun 2003
Location: Waco, Texas
Posts: 630 fractalvibes User rank is Sergeant (500 - 2000 Reputation Level)fractalvibes User rank is Sergeant (500 - 2000 Reputation Level)fractalvibes User rank is Sergeant (500 - 2000 Reputation Level)fractalvibes User rank is Sergeant (500 - 2000 Reputation Level)fractalvibes User rank is Sergeant (500 - 2000 Reputation Level) 
Time spent in forums: 1 Week 11 h 21 m 37 sec
Reputation Power: 21
Thinking that you must be ordering this query by some column,
ID or whatever, and initially might do:
select colA
, colB
, colC
from sometable
order by colA
Fetch first N rows only

itererate through the result set and display those N rows on a page, save off the value of that last column which you are ordering by.

For subsequent pages add a predicate:
where colA > savedLastColAValue

You could save that last value as a Session variable or perhaps as a hidden form field. Perhaps even use that where predicate even in the first page by initially setting the saved value to something less that what you know the min value is for that sorted field..

fv
__________________
...because that is the way we have always done it. We've been doing it like that for 80 Years! (How do we change that mindset?)

Reply With Quote
  #3  
Old June 15th, 2004, 11:42 PM
Onslaught's Avatar
Onslaught Onslaught is offline
/(bb|[^b]{2})/
Dev Shed Demi-God (4500 - 4999 posts)
 
Join Date: Nov 2001
Location: Somewhere in the great unknown
Posts: 4,827 Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level)Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level)Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level)Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level)Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level)Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level)Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level) 
Time spent in forums: 1 Day 22 h 57 m 29 sec
Reputation Power: 88
Send a message via ICQ to Onslaught
It would be great if your table had some unique numeric column like an integer counter. DB2 does not really support pagination style resultsets. Even through cursors and the likes, you are still stuck with the lack of an ability to select only a set from the resultset before it is returned to use except for using fetch first N rows only. The only really plausable solution is one like what fractalvibes listed although you may need to use more than one column depending on how your table is set up. If you have any primary keys set in the table that would be the column(s) to use in the corresponding queries to continue to the next "page" of the resultset.

Reply With Quote
  #4  
Old June 16th, 2004, 12:10 AM
fractalvibes fractalvibes is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: Jun 2003
Location: Waco, Texas
Posts: 630 fractalvibes User rank is Sergeant (500 - 2000 Reputation Level)fractalvibes User rank is Sergeant (500 - 2000 Reputation Level)fractalvibes User rank is Sergeant (500 - 2000 Reputation Level)fractalvibes User rank is Sergeant (500 - 2000 Reputation Level)fractalvibes User rank is Sergeant (500 - 2000 Reputation Level) 
Time spent in forums: 1 Week 11 h 21 m 37 sec
Reputation Power: 21
Yes, ideally you would have an identity column for the table,
but actually a char or date/timestamp column would work.
Basically - whatever you are sorting the result set on...and you would want an index on that column, as Onslaught
says.

fv

Reply With Quote
  #5  
Old June 17th, 2004, 09:49 AM
JimmyGosling's Avatar
JimmyGosling JimmyGosling is offline
Back...with an opinion!
Dev Shed Beginner (1000 - 1499 posts)
 
Join Date: Jun 2004
Location: I invented Java
Posts: 1,033 JimmyGosling User rank is Major (30000 - 40000 Reputation Level)JimmyGosling User rank is Major (30000 - 40000 Reputation Level)JimmyGosling User rank is Major (30000 - 40000 Reputation Level)JimmyGosling User rank is Major (30000 - 40000 Reputation Level)JimmyGosling User rank is Major (30000 - 40000 Reputation Level)JimmyGosling User rank is Major (30000 - 40000 Reputation Level)JimmyGosling User rank is Major (30000 - 40000 Reputation Level)JimmyGosling User rank is Major (30000 - 40000 Reputation Level)JimmyGosling User rank is Major (30000 - 40000 Reputation Level)JimmyGosling User rank is Major (30000 - 40000 Reputation Level) 
Time spent in forums: 2 Weeks 1 Day 17 h 2 m 27 sec
Reputation Power: 385
Thumbs up

thanks for the replies guys. I think I'm going to have to adding in some index of my own, we shall see.
In case ytou do have any other ideas, perhaps a little more infomation on the setup would be in order:
The results are currently sorted on ROW_NR, or the row number corresponding to where they woud be printed out with a full list. The row number assumes that each company will have exactly 10 lines of it's own, and so some row numbers will be missing when there is no more data from the company.
The query can go through two different paths.
Path 1 will print out the full set and so you can get a general idea of how many your getting on each page. For this the query had a start and end page based off of a multiplication of the page*rowsPerPage.
Then there is the second path, where some of those results are missing. There can be a company on row 1-10 and the next company is on row 120-130 then 130-140 and so on. this caused me to switch over to the FETCH FIRST * ROWS statement.
Now, by pulling out the last row I had I would be able to iterate through the pages in order, but this is actually seldom the case. I need to be able to just from page 1 to page 5 and would not have knowledge of where they left off.
The multiplication times the page wwoud work to a certain capacity here. I can multiply the page * rowsPerPage and grab everything leading up to it and delete off the calculated offset, but it's inefficient.

Again, thanks for your help guys. I'm still new on this and always looking for a better way to write my code.

Reply With Quote
  #6  
Old June 17th, 2004, 10:19 AM
fractalvibes fractalvibes is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: Jun 2003
Location: Waco, Texas
Posts: 630 fractalvibes User rank is Sergeant (500 - 2000 Reputation Level)fractalvibes User rank is Sergeant (500 - 2000 Reputation Level)fractalvibes User rank is Sergeant (500 - 2000 Reputation Level)fractalvibes User rank is Sergeant (500 - 2000 Reputation Level)fractalvibes User rank is Sergeant (500 - 2000 Reputation Level) 
Time spent in forums: 1 Week 11 h 21 m 37 sec
Reputation Power: 21
Due to things like deletions, I would not count on the
row after row N to be row N+1...could be some gaps in there.

You need some way after displaying rows 1 through N on a page to persist what that last N was so that for the next page
you can query where colA > N. Might want to also persist the beginning key for a page also, so you can traverse backwards.

fv

Reply With Quote
  #7  
Old June 22nd, 2004, 11:34 PM
dcaillouet's Avatar
dcaillouet dcaillouet is offline
Big Endian
Dev Shed Beginner (1000 - 1499 posts)
 
Join Date: May 2001
Location: Fly-over country
Posts: 1,173 dcaillouet User rank is Sergeant (500 - 2000 Reputation Level)dcaillouet User rank is Sergeant (500 - 2000 Reputation Level)dcaillouet User rank is Sergeant (500 - 2000 Reputation Level)dcaillouet User rank is Sergeant (500 - 2000 Reputation Level)dcaillouet User rank is Sergeant (500 - 2000 Reputation Level) 
Time spent in forums: 16 h 29 m 5 sec
Reputation Power: 24
You didn't specify the language you were using so I'm going to just throw out a couple of suggestions.

1. I access DB2 using C++ most of the time and there is an API function called SQLFetchScroll that allows you to specify FetchOrientation with flags like SQL_FETCH_ABSOLUTE, SQL_FETCH_RELATIVE, SQL_FETCH_BOOKMARK combined with a FetchOffset value to position the cursor to the desired spot.

2. There is a ROW_NUMBER function that allows you to number the rows based on a specified order clause. You can then select on a range of row numbers. I haven't had to use it but it works something like:
Code:
SELECT field1, field2, ..., fieldx, 
       ROW_NUMBER() OVER (ORDER BY field5, field7) AS RN
FROM   tablename
WHERE RN BETWEEN 11 AND 20
ORDER BY RN

You might have to do a little research to get the exact syntax right, but something like this might work. Here's one page that had an example that I was able to Google fairly quickly: http://www.devx.com/getHelpOn/10Min...73/1954?pf=true.

There is also a RANK() function that allows you to do a similar type of sorting. The ROW_NUMBER() and RANK() functions are usually mentioned in relation to OLAP type queries. I'm not sure if every version of DB2 has these functions and I'm not at a machine where I can test it.

Reply With Quote
  #8  
Old June 23rd, 2004, 07:46 AM
Onslaught's Avatar
Onslaught Onslaught is offline
/(bb|[^b]{2})/
Dev Shed Demi-God (4500 - 4999 posts)
 
Join Date: Nov 2001
Location: Somewhere in the great unknown
Posts: 4,827 Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level)Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level)Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level)Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level)Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level)Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level)Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level) 
Time spent in forums: 1 Day 22 h 57 m 29 sec
Reputation Power: 88
Send a message via ICQ to Onslaught
I know about the row_number and rank functionality, I use the rank olap functionality in a couple of queries, but unfortunately I've never been able to get something like your example to work.
Here is an example of what I get when I try it:
Code:
C:\Program Files\SQLLIB\bin>db2 select article, row_number() over (order by article) as rn from my.articles order by rn fetch first 10 rows only

ARTICLE            RN
------------------ --------------------
1234567890                            1
2345678901                            2
3456789012                            3
4567890123                            4
5678901234                            5
6789012345                            6
7890123456                            7
8901234567                            8
9012345678                            9
0123456789                           10

  10 record(s) selected.

C:\Program Files\SQLLIB\bin>db2 select article, row_number() over (order by article) as rn from my.articles where rn between 1 and 10 order by rn
SQL0206N  "RN" is not valid in the context where it is used.  SQLSTATE=42703

C:\Program Files\SQLLIB\bin>db2 select article, row_number() over (order by article) as rn from my.articles where row_number() between 1 and 10 order by rn
SQL0104N  An unexpected token "" was found following "SYSIBM.ROW_NUMBER".
Expected tokens may include:  "OVER".  SQLSTATE=42601

C:\Program Files\SQLLIB\bin>db2 select article, row_number() over (order by article) as rn from my.articles where row_number() over (order by rehau_art) between 1 and 10 order by rn
SQL0120N  A WHERE clause, GROUP BY clause, SET clause, or SET
transition-variable statement contains a column function.  SQLSTATE=42903
I would really like to figure this out in the end on a possible way to do this, but haven't found out a method that is acceptable as of yet unless the table is design to do so. As far as the language goes, we were refering to just sql as a way to do this.

Reply With Quote
  #9  
Old June 23rd, 2004, 07:56 AM
dcaillouet's Avatar
dcaillouet dcaillouet is offline
Big Endian
Dev Shed Beginner (1000 - 1499 posts)
 
Join Date: May 2001
Location: Fly-over country
Posts: 1,173 dcaillouet User rank is Sergeant (500 - 2000 Reputation Level)dcaillouet User rank is Sergeant (500 - 2000 Reputation Level)dcaillouet User rank is Sergeant (500 - 2000 Reputation Level)dcaillouet User rank is Sergeant (500 - 2000 Reputation Level)dcaillouet User rank is Sergeant (500 - 2000 Reputation Level) 
Time spent in forums: 16 h 29 m 5 sec
Reputation Power: 24
I just tested the following query against a UDB 8.1 database. The trick is to alias the initial select by wrapping it in a WITH clause and then selecting from the alias:

Code:
WITH DEVSHEDTEST AS 
(SELECT FIRSTNME, MIDINIT, LASTNAME, SALARY, 
ROW_NUMBER() OVER (ORDER BY SALARY DESC) AS RN 
FROM EMPLOYEE) 
SELECT FIRSTNME, MIDINIT, LASTNAME, SALARY, RN 
FROM DEVSHEDTEST 
WHERE RN BETWEEN 10 AND 15

FIRSTNME     MIDINIT LASTNAME        SALARY      RN
------------ ------- --------------- ----------- --------------------
SEAN                 O'CONNELL          29250.00                   10
SALVATORE    M       MARINO             28760.00                   11
HEATHER      A       NICHOLLS           28420.00                   12
DAVID                BROWN              27740.00                   13
MARIA        L       PEREZ              27380.00                   14
ETHEL        R       SCHNEIDER          26250.00                   15
Comments on this post
Cheesefood agrees: Thanks! This helps me too.

Reply With Quote
  #10  
Old June 23rd, 2004, 09:11 AM
Onslaught's Avatar
Onslaught Onslaught is offline
/(bb|[^b]{2})/
Dev Shed Demi-God (4500 - 4999 posts)
 
Join Date: Nov 2001
Location: Somewhere in the great unknown
Posts: 4,827 Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level)Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level)Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level)Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level)Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level)Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level)Onslaught User rank is Second Lieutenant (5000 - 10000 Reputation Level) 
Time spent in forums: 1 Day 22 h 57 m 29 sec
Reputation Power: 88
Send a message via ICQ to Onslaught
That's what I was missing, you are the man!
This also works with version 7.2.

Reply With Quote
Reply

Viewing: Dev Shed ForumsDatabasesDB2 Development > row offset and fetch first * rows


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

 Free IT White Papers!
 
Accelerating Trading Partner Performance
One in five. That's how many partner transactions have at least one error. That is an amazing statistic, particularly given the extraordinary leaps in innovation across the global supply chain during the past two decades. Download this white paper to learn more.

 
Competing on Analytics
This Tech Analysis is designed to help identify characteristics shared by analytics competitors, and includes information about 32 organizations that have made a commitment to quantitative, fact-based analysis.

 
Cost Effective Scaling with Virtualization and Coyote Point Systems
An overview of the industry trend toward virtualization, how server consolidation has increased the importance of application uptime and the steps being taken to integrate load balancing technology with virtualized servers.

 
Five Checkpoints to Implementing IP Telephony
Implementation planning for IP PBX software and IP telephony has become vital as businesses replace discontinued legacy PBX phone systems. This informative whitepaper outlines five "checkpoints" for any implementation plan that will help make IP communications a successful proposition.

 
Hosted Email Security: Staying Ahead of New Threats
In the last two years, email has become a fierce battleground between the nefarious forces of spam and malware, and the heroes of messaging protection. The spam volumes increased alarmingly every month, bringing clever new forms of phishing and virus propagation attacks.

 

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support |