Cursorless Next/Previous row

Cursorless Next/Previous row

Post by moby7.. » Fri, 09 Jul 1999 04:00:00



I feel like I've forgotten how to do something REAL easy - but I need
help.

How do I select the next/previous record from a table using 1-4 fields
as the reference 'start' point WITHOUT using a cursor?  I've set it up
using several nested ifs, but it is very slow.  The reason, I think, is
the ORDER BY clause needed to sort so I can get the 'Next' or
'Previous' record.

Here's an example of what I've got:

create table test
(
id      char(15) primary key,
lastnm  char(15),
firstnm char(15),
mi      char(1)
)

CREATE INDEX ix_name ON test (lastnm, firstnm, mi, id)

At this point I have 2 indexes.  Obviously, I can do a search and
quickly get any record.  The problem is when I try to do an 'ORDER BY'
to determine which record is 'Next', it appears to have to sort the
entire result set, and not just show me the next record.

HELP!! - Any help is appreciated.

Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.

 
 
 

Cursorless Next/Previous row

Post by Ron Talmag » Fri, 09 Jul 1999 04:00:00


Moby,

You can store the index result in a variable and requery the table, finding
the minimum of what's left. Let's assume you're searching by id. For
example, you do your first SELECT to get the id



mi = 'E'
-- To get the 'next' one,
SELECT MIN(id)
    FROM test

etc.

Ron
Ron Talmage
SQL Server MVP, MCSD, MCP

--

DECLARE


>I feel like I've forgotten how to do something REAL easy - but I need
>help.

>How do I select the next/previous record from a table using 1-4 fields
>as the reference 'start' point WITHOUT using a cursor?  I've set it up
>using several nested ifs, but it is very slow.  The reason, I think, is
>the ORDER BY clause needed to sort so I can get the 'Next' or
>'Previous' record.

>Here's an example of what I've got:

>create table test
>(
>id char(15) primary key,
>lastnm char(15),
>firstnm char(15),
>mi char(1)
>)

>CREATE INDEX ix_name ON test (lastnm, firstnm, mi, id)

>At this point I have 2 indexes.  Obviously, I can do a search and
>quickly get any record.  The problem is when I try to do an 'ORDER BY'
>to determine which record is 'Next', it appears to have to sort the
>entire result set, and not just show me the next record.

>HELP!! - Any help is appreciated.

>Sent via Deja.com http://www.deja.com/
>Share what you know. Learn what you don't.


 
 
 

Cursorless Next/Previous row

Post by moby7.. » Sat, 10 Jul 1999 04:00:00


Thanks for the quick response, but my original post was misleading.
The column id is not an incremental counter, but ANYTHING from a Social
Security number to 'ZZASSEA1123'.

Your suggestion would show me the id that comes after the person named
Grace E Jones, not the name that comes after Grace E Jones.

What I'd like to be able to do is to quickly find the below sequence,
ONE AT A TIME mind you, regardless of the id:

LAST NAME  FIRST NAME       MI        ID
.
.
.
JONES      GRACE            E         97655222
JONES      GRACE            E         00000001
JONES      GRACE            F         AHHEDS
JONES      GRETTA           Z         100LLP-AA
JUPPO      BOB                        19980701
.
.
.

Thanks again for any additional help.



> Moby,

> You can store the index result in a variable and requery the table,
finding
> the minimum of what's left. Let's assume you're searching by id. For
> example, you do your first SELECT to get the id



'Grace' AND
> mi = 'E'
> -- To get the 'next' one,
> SELECT MIN(id)
>     FROM test

> etc.

> Ron
> Ron Talmage
> SQL Server MVP, MCSD, MCP

> --

> DECLARE



- Show quoted text -

Quote:> >I feel like I've forgotten how to do something REAL easy - but I
need
> >help.

> >How do I select the next/previous record from a table using 1-4
fields
> >as the reference 'start' point WITHOUT using a cursor?  I've set it
up
> >using several nested ifs, but it is very slow.  The reason, I think,
is
> >the ORDER BY clause needed to sort so I can get the 'Next' or
> >'Previous' record.

> >Here's an example of what I've got:

> >create table test
> >(
> >id char(15) primary key,
> >lastnm char(15),
> >firstnm char(15),
> >mi char(1)
> >)

> >CREATE INDEX ix_name ON test (lastnm, firstnm, mi, id)

> >At this point I have 2 indexes.  Obviously, I can do a search and
> >quickly get any record.  The problem is when I try to do an 'ORDER
BY'
> >to determine which record is 'Next', it appears to have to sort the
> >entire result set, and not just show me the next record.

> >HELP!! - Any help is appreciated.

> >Sent via Deja.com http://www.deja.com/
> >Share what you know. Learn what you don't.

Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
 
 
 

Cursorless Next/Previous row

Post by OTIS » Sat, 10 Jul 1999 04:00:00


This may be easier to do using Cursors than any other way.  Cursors are the
official SQL way of performing individual record based (rather than set
based) operations.   It would be interesting to hear alternatives from the
Gurus of this newsgroup who have helped me out a number of times.  Ron is
one, but there are a number of others who I won't name because I'm afraid
I'll leave someone out.  Hope that this helps (or that someone else does).

>Thanks for the quick response, but my original post was misleading.
>The column id is not an incremental counter, but ANYTHING from a Social
>Security number to 'ZZASSEA1123'.

>Your suggestion would show me the id that comes after the person named
>Grace E Jones, not the name that comes after Grace E Jones.

>What I'd like to be able to do is to quickly find the below sequence,
>ONE AT A TIME mind you, regardless of the id:

>LAST NAME  FIRST NAME       MI        ID
>.
>.
>.
>JONES      GRACE            E         97655222
>JONES      GRACE            E         00000001
>JONES      GRACE            F         AHHEDS
>JONES      GRETTA           Z         100LLP-AA
>JUPPO      BOB                        19980701
>.
>.
>.

>Thanks again for any additional help.



>> Moby,

>> You can store the index result in a variable and requery the table,
>finding
>> the minimum of what's left. Let's assume you're searching by id. For
>> example, you do your first SELECT to get the id



>'Grace' AND
>> mi = 'E'
>> -- To get the 'next' one,
>> SELECT MIN(id)
>>     FROM test

>> etc.

>> Ron
>> Ron Talmage
>> SQL Server MVP, MCSD, MCP

>> --

>> DECLARE


>> >I feel like I've forgotten how to do something REAL easy - but I
>need
>> >help.

>> >How do I select the next/previous record from a table using 1-4
>fields
>> >as the reference 'start' point WITHOUT using a cursor?  I've set it
>up
>> >using several nested ifs, but it is very slow.  The reason, I think,
>is
>> >the ORDER BY clause needed to sort so I can get the 'Next' or
>> >'Previous' record.

>> >Here's an example of what I've got:

>> >create table test
>> >(
>> >id char(15) primary key,
>> >lastnm char(15),
>> >firstnm char(15),
>> >mi char(1)
>> >)

>> >CREATE INDEX ix_name ON test (lastnm, firstnm, mi, id)

>> >At this point I have 2 indexes.  Obviously, I can do a search and
>> >quickly get any record.  The problem is when I try to do an 'ORDER
>BY'
>> >to determine which record is 'Next', it appears to have to sort the
>> >entire result set, and not just show me the next record.

>> >HELP!! - Any help is appreciated.

>> >Sent via Deja.com http://www.deja.com/
>> >Share what you know. Learn what you don't.

>Sent via Deja.com http://www.deja.com/
>Share what you know. Learn what you don't.

 
 
 

Cursorless Next/Previous row

Post by Roy Harv » Sat, 10 Jul 1999 04:00:00


Moby,

Quote:>What I'd like to be able to do is to quickly find the below sequence,
>ONE AT A TIME mind you, regardless of the id:

>LAST NAME  FIRST NAME       MI        ID
>.
>.
>.
>JONES      GRACE            E         97655222
>JONES      GRACE            E         00000001
>JONES      GRACE            F         AHHEDS
>JONES      GRETTA           Z         100LLP-AA
>JUPPO      BOB                        19980701
>.
>.

I worked on this for a few minutes and it just is NOT going to be
simple enough or efficient enough to implement as a single query.  I
suggest two passes.  In the first we retrieve the next or prior value
of lastname, and in the second use that to limit the scope of a
cursor.  For the case where you want the prior row:


  FROM tbl

Then the select to put in the cursor:

SELECT *
  FROM tbl

 ORDER BY lastname, firstname, mi, id

Finding your way around the cursor is your problem - I hate cursors!
8-)

Roy

 
 
 

Cursorless Next/Previous row

Post by Trys » Sun, 11 Jul 1999 04:00:00


Greetings,
This should mimic the prior cursor.



SELECT Distinct b.lname,b.fname,b.[id]
FROM tbl AS a INNER JOIN tbl AS b
ON (SELECT Max(e.lname+e.fname) FROM tbl AS e WHERE e.lname+e.fname<
a.lname+a.fname )<=b.lname+b.fname

ORDER BY 1,2

Please don't cursor me.

Steve Dassin


>>What I'd like to be able to do is to quickly find the below sequence,
>>ONE AT A TIME mind you, regardless of the id:
>>LAST NAME  FIRST NAME       MI        ID
>>.
>>JONES      GRACE            E         97655222
>>JONES      GRACE            E         00000001
>>JONES      GRACE            F         AHHEDS
>>JONES      GRETTA           Z         100LLP-AA
>>JUPPO      BOB                        19980701
>I worked on this for a few minutes and it just is NOT going to be
>simple enough or efficient enough to implement as a single query.  I
>suggest two passes.  In the first we retrieve the next or prior value
>of lastname, and in the second use that to limit the scope of a
>cursor.  For the case where you want the prior row:

>  FROM tbl

>Then the select to put in the cursor:
>SELECT *
>  FROM tbl

> ORDER BY lastname, firstname, mi, id
>Finding your way around the cursor is your problem - I hate cursors!
>8-)

 
 
 

Cursorless Next/Previous row

Post by North Hinkl » Sun, 11 Jul 1999 04:00:00


Moby,

Ron did show you how.  The problem is he demonstrated the set from which you
want to select your records; i.e.

Select ...
from....
where key < current_key
order by LNAME, FNAME, MI

Given a current key of
LNAME    FNAME    MI
JONES    GRACE    A

The first row returned would be:

Quote:>JONES      GRACE            F         AHHEDS

To get just the first row, use the TOP qualifier; i.e.:
Select TOP 1 ...
from....
where key < current_key
order by LNAME, FNAME, MI

This will be fast if you have an index on LNAME, FNAME, MI.

With 7.0, it may hiccup on common names like SMITH and Jones, as FNAME may
be more selective.  In the case where this happens too often, you might want
three indices: one each on LNAME, FNAME, MI.  The access path will be a
index hash join, just make sure you do not have any "OR" qualifications in
your join or where clause (forces you back to nested iteration - can be
slow).

North


>Thanks for the quick response, but my original post was misleading.
>The column id is not an incremental counter, but ANYTHING from a Social
>Security number to 'ZZASSEA1123'.

>Your suggestion would show me the id that comes after the person named
>Grace E Jones, not the name that comes after Grace E Jones.

>What I'd like to be able to do is to quickly find the below sequence,
>ONE AT A TIME mind you, regardless of the id:

>LAST NAME  FIRST NAME       MI        ID
>.
>.
>.
>JONES      GRACE            E         97655222
>JONES      GRACE            E         00000001
>JONES      GRACE            F         AHHEDS
>JONES      GRETTA           Z         100LLP-AA
>JUPPO      BOB                        19980701
>.
>.
>.

>Thanks again for any additional help.



>> Moby,

>> You can store the index result in a variable and requery the table,
>finding
>> the minimum of what's left. Let's assume you're searching by id. For
>> example, you do your first SELECT to get the id



>'Grace' AND
>> mi = 'E'
>> -- To get the 'next' one,
>> SELECT MIN(id)
>>     FROM test

>> etc.

>> Ron
>> Ron Talmage
>> SQL Server MVP, MCSD, MCP

>> --

>> DECLARE


>> >I feel like I've forgotten how to do something REAL easy - but I
>need
>> >help.

>> >How do I select the next/previous record from a table using 1-4
>fields
>> >as the reference 'start' point WITHOUT using a cursor?  I've set it
>up
>> >using several nested ifs, but it is very slow.  The reason, I think,
>is
>> >the ORDER BY clause needed to sort so I can get the 'Next' or
>> >'Previous' record.

>> >Here's an example of what I've got:

>> >create table test
>> >(
>> >id char(15) primary key,
>> >lastnm char(15),
>> >firstnm char(15),
>> >mi char(1)
>> >)

>> >CREATE INDEX ix_name ON test (lastnm, firstnm, mi, id)

>> >At this point I have 2 indexes.  Obviously, I can do a search and
>> >quickly get any record.  The problem is when I try to do an 'ORDER
>BY'
>> >to determine which record is 'Next', it appears to have to sort the
>> >entire result set, and not just show me the next record.

>> >HELP!! - Any help is appreciated.

>> >Sent via Deja.com http://www.deja.com/
>> >Share what you know. Learn what you don't.

>Sent via Deja.com http://www.deja.com/
>Share what you know. Learn what you don't.

 
 
 

Cursorless Next/Previous row

Post by Trys » Sun, 11 Jul 1999 04:00:00


Hi North,
Thanks for being at the TOP of your game.

Prior cursor (including all dups) is:



select a.lname as lname,a.fname as fname,a.[id]
from
(select top 1 lname,fname,lname+fname AS dumy,[id]
from tbl

order by lname+fname desc ) AS a
inner join tbl AS b
on a.lname+a.fname=b.lname+b.fname
union all
select lname,fname,[id]

order by lname,fname

Steve Dassin


>Ron did show you how.  The problem is he demonstrated the set from which you
>want to select your records; i.e.

>Select ...
>from....
>where key < current_key
>order by LNAME, FNAME, MI

>Given a current key of
>LNAME    FNAME    MI
>JONES    GRACE    A

>The first row returned would be:
>>JONES      GRACE            F         AHHEDS

>To get just the first row, use the TOP qualifier; i.e.:
>Select TOP 1 ...
>from....
>where key < current_key
>order by LNAME, FNAME, MI

>This will be fast if you have an index on LNAME, FNAME, MI.

>With 7.0, it may hiccup on common names like SMITH and Jones, as FNAME may
>be more selective.  In the case where this happens too often, you might want
>three indices: one each on LNAME, FNAME, MI.  The access path will be a
>index hash join, just make sure you do not have any "OR" qualifications in
>your join or where clause (forces you back to nested iteration - can be
>slow).

>North


>>Thanks for the quick response, but my original post was misleading.
>>The column id is not an incremental counter, but ANYTHING from a Social
>>Security number to 'ZZASSEA1123'.

>>Your suggestion would show me the id that comes after the person named
>>Grace E Jones, not the name that comes after Grace E Jones.

>>What I'd like to be able to do is to quickly find the below sequence,
>>ONE AT A TIME mind you, regardless of the id:

>>LAST NAME  FIRST NAME       MI        ID
>>.
>>.
>>.
>>JONES      GRACE            E         97655222
>>JONES      GRACE            E         00000001
>>JONES      GRACE            F         AHHEDS
>>JONES      GRETTA           Z         100LLP-AA
>>JUPPO      BOB                        19980701
>>.
>>Thanks again for any additional help.



>>> Moby,

>>> You can store the index result in a variable and requery the table,
>>finding
>>> the minimum of what's left. Let's assume you're searching by id. For
>>> example, you do your first SELECT to get the id



>>'Grace' AND
>>> mi = 'E'
>>> -- To get the 'next' one,
>>> SELECT MIN(id)
>>>     FROM test

>>> etc.

>>> Ron
>>> Ron Talmage
>>> SQL Server MVP, MCSD, MCP
>>> --

>>> DECLARE


>>> >I feel like I've forgotten how to do something REAL easy - but I
>>need
>>> >help.

>>> >How do I select the next/previous record from a table using 1-4
>>fields
>>> >as the reference 'start' point WITHOUT using a cursor?  I've set it
>>up
>>> >using several nested ifs, but it is very slow.  The reason, I think,
>>is
>>> >the ORDER BY clause needed to sort so I can get the 'Next' or
>>> >'Previous' record.

>>> >Here's an example of what I've got:

>>> >create table test
>>> >(
>>> >id char(15) primary key,
>>> >lastnm char(15),
>>> >firstnm char(15),
>>> >mi char(1)
>>> >CREATE INDEX ix_name ON test (lastnm, firstnm, mi, id)
>>> >At this point I have 2 indexes.  Obviously, I can do a search and
>>> >quickly get any record.  The problem is when I try to do an 'ORDER
>>BY'
>>> >to determine which record is 'Next', it appears to have to sort the
>>> >entire result set, and not just show me the next record.

 
 
 

Cursorless Next/Previous row

Post by North Hinkl » Sun, 11 Jul 1999 04:00:00


Way to string it together Steve.

Still, I feel like we are banging are heads against the wall.

Sets are not ordered, so why do we write applications as if they are?

btw, being the youngest of 6, I am obviously not a top descendant... ;-)

North


>Hi North,
>Thanks for being at the TOP of your game.

>Prior cursor (including all dups) is:



>select a.lname as lname,a.fname as fname,a.[id]
>from
>(select top 1 lname,fname,lname+fname AS dumy,[id]
>from tbl

>order by lname+fname desc ) AS a
>inner join tbl AS b
>on a.lname+a.fname=b.lname+b.fname
>union all
>select lname,fname,[id]

>order by lname,fname

>Steve Dassin

 
 
 

1. Cursorless Next/Previous row

I feel like I've forgotten how to do something
REAL easy - but I need help.

How do I select the next/previous record from a
table using 1-4 fields as the reference 'start'
point WITHOUT using a cursor?  I've set it up
using several nested ifs, but it is very slow.
The reason, I think, is the ORDER BY clause
needed to sort so I can get the 'Next' or
'Previous' record.

Here's an example of what I've got:

create table test
(
id      char(15) primary key,
lastnm  char(15),
firstnm char(15),
mi      char(1)
)

CREATE INDEX ix_name ON test (lastnm, firstnm,
mi, id)

At this point I have 2 indexes.  Obviously, I can
do a search and quickly get any record.  The
problem is when I try to do an 'ORDER BY' to
determine which record is 'Next', it appears to
have to sort the entire result set, and not just
show me the next record.

HELP!! - Any help is appreciated.

Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.

2. Emulate aggregate function using UDF?

3. I need previous and next rows!!!

4. Update table with DTS

5. How to get the next or previous indexed row

6. Error when accessing an Access driven page multiple times in one session.

7. Oracle : Next/Previous row selection

8. problem on informix sql

9. Enter,Next Row and Clear for Next record

10. How to use Select statement and optimize it for using previous and next records

11. Retrieve next and previous records

12. Next and Previous impl.

13. Previous and Next record surrounding one specific record