473,396 Members | 2,059 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Select the 2nd of a sequence of rows in a table

Hello,

DB2 for iSeries - V5R2

I have a table with a non-unique index, column name SEDOL.

I need to extract the 2nd row from each set of SEDOL rows in the table.
If only one SEDOL row exists then select that one row.

As an example:

SEDOL STATUS

10000 A
10001 A
10001 B
10001 C
10001 D
10050 A
10050 B
10051 A
10100 A
10100 B

So, I need to extract

10000 A
10001 B
10050 B
10051 A
10100 B

Suggestions on how I do this would be welcome.

Thanks

Glenn

Mar 14 '06 #1
17 6061
gl************@quattroconsulting.co.uk wrote:
Hello,

DB2 for iSeries - V5R2

I have a table with a non-unique index, column name SEDOL.

I need to extract the 2nd row from each set of SEDOL rows in the
table. If only one SEDOL row exists then select that one row.

As an example:

SEDOL STATUS

10000 A
10001 A
10001 B
10001 C
10001 D
10050 A
10050 B
10051 A
10100 A
10100 B

So, I need to extract

10000 A
10001 B
10050 B
10051 A
10100 B

Suggestions on how I do this would be welcome.

Thanks

Glenn


Hmmm... Something like this maybe? Probably not the best solution, but
it seems to work (BTW, I've assumed the table is called SEDOLTABLE):

WITH
SEDOL1 AS (
SELECT SEDOL, COUNT(*) AS ROWCOUNT
FROM SEDOLTABLE
GROUP BY SEDOL
),
SEDOL2 AS (
SELECT SEDOL, STATUS, ROW_NUMBER() OVER (PARTITION BY SEDOL
ORDER BY STATUS) AS ROWNUM
FROM SEDOLTABLE
),
SEDOL3 AS (
SELECT B.SEDOL, B.STATUS, B.ROWNUM, A.ROWCOUNT
FROM SEDOL1 A INNER JOIN SEDOL2 B ON A.SEDOL = B.SEDOL
)

SELECT SEDOL, STATUS
FROM SEDOL3
WHERE
(ROWCOUNT = 1) OR
(ROWCOUNT > 1 AND ROWNUM = 2);
HTH,

Dave.
--

Mar 14 '06 #2
aj
<laughing>
No answer for your question, but:

Interestingly enough, I know exactly what a SEDOL is..
The hours that I have spent with those and CUSIPs...

Cheers

aj

gl************@quattroconsulting.co.uk wrote:
Hello,

DB2 for iSeries - V5R2

I have a table with a non-unique index, column name SEDOL.

I need to extract the 2nd row from each set of SEDOL rows in the table.
If only one SEDOL row exists then select that one row.

As an example:

SEDOL STATUS

10000 A
10001 A
10001 B
10001 C
10001 D
10050 A
10050 B
10051 A
10100 A
10100 B

So, I need to extract

10000 A
10001 B
10050 B
10051 A
10100 B

Suggestions on how I do this would be welcome.

Thanks

Glenn

Mar 14 '06 #3
Dave,

I knew there'd be a way. Still not found a query that SQL can't handle.

Thanks for this.

Glenn

Mar 14 '06 #4
gl************@quattroconsulting.co.uk wrote:
Dave,

I knew there'd be a way. Still not found a query that SQL can't
handle.

Thanks for this.

Glenn


Glenn - I've just re-read your initial post and noticed you mentioned
that you're running this on DB2 V5R2 ... I must admit I haven't taken
that into consideration in the query. I can't remember if common table
expressions (WITH) or OLAP functions (ROW_NUMBER) are available under
that version.

Anyway, give it a try and if it doesn't work I'll see if I can figure
out another method...
Cheers,

Dave.
--

Mar 15 '06 #5
Hello.

If you don't afraid of java UDF mail me at
mark(dot)b(at)mail(dot)ru
I can send you fairly small java class and sql for creation java UDF
that tries to emulate rownumber function in UDB DB2 for LUW.
With this function you will be able to do this:
-----
declare global temporary table session.t
(
sedol int, status char(1)
) with replace on commit preserve rows not logged;

insert into session.t values (10000, 'A');
insert into session.t values (10001, 'A');
insert into session.t values (10001, 'B');
insert into session.t values (10001, 'C');
insert into session.t values (10001, 'D');
insert into session.t values (10050, 'A');
insert into session.t values (10050, 'B');
insert into session.t values (10051, 'A');
insert into session.t values (10100, 'A');
insert into session.t values (10100, 'B');

-- we have to order rows befor enumerating them
declare global temporary table session.t2 as
(
select * from session.t order by sedol, status
) with data with replace on commit preserve rows not logged;

with t (sedol, status, rn) as
(
select sedol, status, dwh.rownumber(char(sedol), 16) as rn
from session.t2
)
select t1.sedol, coalesce(t2.status, t1.status) as status
from t t1
left join t t2 on t1.sedol=t2.sedol and t2.rn=2
where t1.rn=1;
-----
output:
----
SEDOL STATUS
--------------- ------
10000 A
10001 B
10050 B
10051 A
10100 B

5 record(s) selected.
----

Sincerely,
Mark B.

Mar 15 '06 #6
Dave Hughes wrote:
gl************@quattroconsulting.co.uk wrote:
Dave,

I knew there'd be a way. Still not found a query that SQL can't
handle.

Thanks for this.

Glenn


Glenn - I've just re-read your initial post and noticed you mentioned
that you're running this on DB2 V5R2 ... I must admit I haven't taken
that into consideration in the query. I can't remember if common table
expressions (WITH) or OLAP functions (ROW_NUMBER) are available under
that version.

Anyway, give it a try and if it doesn't work I'll see if I can figure
out another method...


An alternative could be this:

SELECT ...
FROM t AS t1
WHERE status = ( SELECT MAX(status)
FROM t AS t2
WHERE status < ( SELECT MAX(status)
FROM t AS t3
WHERE t3.sedol = t1.sedol ) AND
t2.sedol = t1.sedol )

If you wont to get the 3rd, 4th and so on, things will become more
complicated. Using the ROW_NUMBER/RANK function would be a better choice
then.

--
Knut Stolze
DB2 Information Integration Development
IBM Germany
Mar 15 '06 #7
Knut Stolze wrote:
Dave Hughes wrote:
gl************@quattroconsulting.co.uk wrote:
Dave,

I knew there'd be a way. Still not found a query that SQL can't
handle.

Thanks for this.

Glenn


Glenn - I've just re-read your initial post and noticed you mentioned
that you're running this on DB2 V5R2 ... I must admit I haven't taken
that into consideration in the query. I can't remember if common table
expressions (WITH) or OLAP functions (ROW_NUMBER) are available under
that version.

Anyway, give it a try and if it doesn't work I'll see if I can figure
out another method...


An alternative could be this:

SELECT ...
FROM t AS t1
WHERE status = ( SELECT MAX(status)
FROM t AS t2
WHERE status < ( SELECT MAX(status)
FROM t AS t3
WHERE t3.sedol = t1.sedol ) AND
t2.sedol = t1.sedol )


I forgot the case when there is only one row:

UNION
SELECT ...
FROM t AS t4
WHERE 1 = ( SELECT COUNT(*)
FROM t AS t5
WHERE t4.sedol = t5.sedol )

--
Knut Stolze
DB2 Information Integration Development
IBM Germany
Mar 15 '06 #8
Or, with just OLAP (no with):

SELECT SEDOL, STATUS
FROM (SELECT SEDOL, STATUS,
ROW_NUMBER() OVER (PARTITION BY SEDOL ORDER BY STATUS) AS
ROWNUM,
COUNT(*) OVER (PARTITION BY SEDOL) AS ROWCOUNT ) X
WHERE (ROWCOUNT < 3 AND ROWNUM = ROWCOUNT)
OR (ROWCOUNT > 2 AND ROWCOUNT = 2)

Mar 15 '06 #9
Let's get back to the basics of an RDBMS. Rows are not records; fields
are not columns; tables are not files; there is no sequential access or
ordering in an RDBMS, so "first", "next" and "last" are totally
meaningless. If you want an ordering, then you need to have a column
that defines that ordering. You must use an ORDER BY clause on a
cursor or in an OVER() clause.

Next, please the good manners to post DDL for people who are doing your
job or homework for free. Here is an answer in pure SQL-92, without
SQL-99 OLAP features.

CREATE TABLE Foobar
(sedol INTEGER NOT NULL, -- industry standard term??
foobar_status CHAR(1) NOT NULL,
PRIMARY KEY (sedol, foobar_status));

INSERT INTO Foobar VALUES (10000, 'A');
INSERT INTO Foobar VALUES (10001, 'A');
INSERT INTO Foobar VALUES (10001, 'B');
INSERT INTO Foobar VALUES (10001, 'C');
INSERT INTO Foobar VALUES (10001, 'D');
INSERT INTO Foobar VALUES (10050, 'A');
INSERT INTO Foobar VALUES (10050, 'B');
INSERT INTO Foobar VALUES (10051, 'A');
INSERT INTO Foobar VALUES (10100, 'A');
INSERT INTO Foobar VALUES (10100, 'B');
*/

SELECT F0.sedol,
CASE WHEN MIN(F0.foobar_status) = MAX(F0.foobar_status)
THEN MIN(foobar_status)
ELSE (SELECT MIN(F1.foobar_status)
FROM Foobar AS F1
WHERE F1.foobar_status
(SELECT MIN(F2.foobar_status)

FROM Foobar AS F2
WHERE F2.sedol = F0.sedol))
END
FROM Foobar AS F0
GROUP BY F0.sedol;

Mar 15 '06 #10
On Wed, 15 Mar 2006 20:22:11 UTC "--CELKO--" <jc*******@earthlink.net>
wrote:
Let's get back to the basics of an RDBMS. Rows are not records; fields
are not columns; tables are not files; there is no sequential access or
ordering in an RDBMS, so "first", "next" and "last" are totally
meaningless. If you want an ordering, then you need to have a column
that defines that ordering. You must use an ORDER BY clause on a
cursor or in an OVER() clause.

Next, please the good manners to post DDL for people who are doing your
job or homework for free. Here is an answer in pure SQL-92, without
SQL-99 OLAP features.


I'll try and be precise <g>. What you are doing brings to mind
another situation involving one-to-many and many-to-one situations
that I have been brute forcing for years with coding inside the
application. The specific case here is a membership list. Every
member has a unique identifier but names, addresses, and (especially)
email addresses may be duplicated (the case of multiple family members
using a common email address). What I could really use is a clean
way to select any one of the resulting multiple matches when the only
search critierion is the email address. If it would work, qualifying
the selection with FETCH FIRST 1 ROWS ONLY would be ideal - it is the
exact logic I want- but that does not work for an update function
when I try and use a list of email addresses to give the user a
contact list from the email reply list he hands me.

I'm using V 7.2 here and the master list is essentially a single
table, so is there a straight forward way to do this in dynamic SQL?

--
Will Honea
Mar 16 '06 #11
Knut,

This looks like the best solution for my situation, thanks.

Because the system is still at V5R2 I don't have OLAP functions
available.

Glenn

Mar 16 '06 #12
--CELKO-- wrote:
Let's get back to the basics of an RDBMS. Rows are not records; fields
are not columns; tables are not files; there is no sequential access or
ordering in an RDBMS, so "first", "next" and "last" are totally
meaningless. If you want an ordering, then you need to have a column
that defines that ordering.


You have to have an _expression_ that defines the ordering. ;-)

--
Knut Stolze
DB2 Information Integration Development
IBM Germany
Mar 16 '06 #13
gl************@quattroconsulting.co.uk wrote:
Knut,

This looks like the best solution for my situation, thanks.

Because the system is still at V5R2 I don't have OLAP functions
available.


Let us know if this does not work. I just typed it in without verifying the
syntax...

--
Knut Stolze
DB2 Information Integration Development
IBM Germany
Mar 16 '06 #14
Knut Stolze wrote:
gl************@quattroconsulting.co.uk wrote:

Knut,

This looks like the best solution for my situation, thanks.

Because the system is still at V5R2 I don't have OLAP functions
available.

Let us know if this does not work. I just typed it in without verifying the
syntax...


We did try this yesterday but we had to coancel it after 1.5 hours, it
was still running. The table has about 250,000 roes so it's not that big.

I think I've come to the decision that I'm better off using an HLL to do
this.

I think I can use an ILE RPG porgram of about 20 lines to do this. Right
tool for the job I believe.

Thanks anyway.
Glenn
Mar 17 '06 #15
It looks as if status is always the second letter in the alphabet on a
"second" row. Is that always true?

Because, if so. a simple query such as

SELECT SEDOL, MAX(STATUS) FROM table WHERE Status IN ('A', 'B') GROUP
BY SEDOL

B.

Mar 17 '06 #16
SELECT SEDOL
, MAX(STATUS) AS STATUS
FROM SEDOLTBL T1
WHERE (SELECT COUNT(*)
FROM SEDOLTBL T2
WHERE T2.SEDOL = T1.SEDOL
AND T2.STATUS <= T1.STATUS
) <= 2
GROUP BY
SEDOL;
---------------------------------------------------
SEDOL STATUS
----------- ------
10000 A
10001 B
10050 B
10051 A
10100 B

Mar 17 '06 #17
Wow, Tonkuma, that's good. And so simple too. :)

B.

Mar 20 '06 #18

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: Andrew Baker | last post by:
What is the best way to lock an individual row in the following scenerio: --TODO - LOCK THIS ROW -- Return the next id SELECT next_id INTO next_id_out FROM owner.my_id_table WHERE app_id =...
3
by: Alex | last post by:
Hi, I need to form a query where i can add some columns based on the result. Table A ColA, ColB ---------- 1 A 2 B
6
by: Bjørn T Johansen | last post by:
I need to maintain a manually counter for an id-field, but I can do this two ways. Either make a counter table (which means one select and one update) or just selecting the largest id from existing...
12
by: TP | last post by:
Here is my problem. I need to display a table about which I have no information except the table name. Using metadata I can somehow show the column names and record values. But my table has 1...
1
by: Diffident | last post by:
Hello All, I am trying to filter rows in a datatable based on filtercriteria and sortcriteria using the datatable.select() method. I am encountering a strange behavior in this process. Here is...
4
by: Ed L. | last post by:
I think I'm seeing table-level lock contention in the following function when I have many different concurrent callers, each with mutually distinct values for $1. Is there a way to reimplement...
1
by: Grant McLean | last post by:
Hi First a simple question ... I have a table "access_log" that has foreign keys "app_id" and "app_user_id" that reference the "application_type" and "app_user" tables. When I insert into...
19
by: Steve | last post by:
ASP error number 13 - Type mismatch with SELECT...FOR UPDATE statement I got ASP error number 13 when I use the SELECT...FOR UPDATE statement as below. However, if I use SELECT statement without...
4
by: bboyle18 | last post by:
Hi, I am working with a table sorting script which can be found here http://www.workingwith.me.uk/articles/scripting/standardista_table_sorting This script works very nicely, but when there is a...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.