Yeti
asked on
How to select only row 5 to 19 or row 20 to 299 from a table?
I know you can, quite easily, select the TOP 15 or 20 or 300 rows of a table, but is there a way to select 16-19? or 21-299?
I need it to fill a listview only with as many elements as the listview can display at once, and when the user scrolls up or down I want to fill the listview with the next n elements.
The table I need to show consists of hundreds of thousands of rows and to return all rows would be a performance nightmare.
Can you provide a sample code of how it could be done using a stored procedure?
Thanks in advance,
Roberto.
I need it to fill a listview only with as many elements as the listview can display at once, and when the user scrolls up or down I want to fill the listview with the next n elements.
The table I need to show consists of hundreds of thousands of rows and to return all rows would be a performance nightmare.
Can you provide a sample code of how it could be done using a stored procedure?
Thanks in advance,
Roberto.
you can use cursor.
i will test it and give you a result
i will test it and give you a result
I would actually recommend against a cursor or temporary table for this application. While I understand the motivation, I think a one-time hit might work better performance-wise than the constant traffic that would be necessary to browse the list. Have a question about browsing potentially "hundreds of thousands of rows" in a ListView, but that's another topic. An alternative is to populate the ListView using a disconnected recordset. This recordset can be created asynchronously at the start of the application to minimize the impact to users.
Here's an example of the kind of thing I'd suggest:
CREATE TABLE stp_YourProcedure
@sintStartRecord INTEGER,
@sintEndRecord INTEGER
AS
BEGIN
CREATE TABLE #ptblRecords
(
intRecordNumber INTEGER IDENTITY(1,1),
strFieldOne VARCHAR(100)
)
INSERT #ptblRecords
SELECT FieldOne
FROM YourTable
SELECT * FROM #ptblRecords
WHERE intRecordNumber BETWEEN @sintStartRecord AND @sintEndRecord
DROP TABLE #ptblRecords
END
CREATE TABLE stp_YourProcedure
@sintStartRecord INTEGER,
@sintEndRecord INTEGER
AS
BEGIN
CREATE TABLE #ptblRecords
(
intRecordNumber INTEGER IDENTITY(1,1),
strFieldOne VARCHAR(100)
)
INSERT #ptblRecords
SELECT FieldOne
FROM YourTable
SELECT * FROM #ptblRecords
WHERE intRecordNumber BETWEEN @sintStartRecord AND @sintEndRecord
DROP TABLE #ptblRecords
END
--This will return records 15-25 assuming that you have an identity field.
SELECT TOP 10 * FROM TABLENAME WHERE IDENTITY_FIELD_FALUE >= 15
SELECT TOP 10 * FROM TABLENAME WHERE IDENTITY_FIELD_FALUE >= 15
If you have some kind of key value or sequence (for example, name or id number), then you do something like the following:
--this would actually likely be application code,
--not db code, but the logic is the same
DECLARE @lastKey INT
DECLARE @numRows INT
SET @lastKey = 0 --if first time thru
SET @numRows = 20 --or whatever
Loop:
--this code would be passed as a batch to db to exec
SET ROWCOUNT @numRows
SELECT ...
FROM ...
WHERE keyCol > @lastKey
--put returned rows into list
--user uses current list, requests next page ...
--save value of last entry added to list and get more
SET @lastKey = last_key_in_list
GOTO Loop
--this would actually likely be application code,
--not db code, but the logic is the same
DECLARE @lastKey INT
DECLARE @numRows INT
SET @lastKey = 0 --if first time thru
SET @numRows = 20 --or whatever
Loop:
--this code would be passed as a batch to db to exec
SET ROWCOUNT @numRows
SELECT ...
FROM ...
WHERE keyCol > @lastKey
--put returned rows into list
--user uses current list, requests next page ...
--save value of last entry added to list and get more
SET @lastKey = last_key_in_list
GOTO Loop
You can use subquery like this:
--
SELECT TOP [n] k_field, field_a, field_b, ....
FROM myTable
WHERE k_field not in (
select TOP [m] k_field
FROM myTable
ORDER BY k_field)
ORDER BY k_field
--
where:
[n] is the number of rows to be returned (row per page)
[m] is the ordinal position of the first row returned (0=return the first row, 1=return the 2 row, etc.).
--
SELECT TOP [n] k_field, field_a, field_b, ....
FROM myTable
WHERE k_field not in (
select TOP [m] k_field
FROM myTable
ORDER BY k_field)
ORDER BY k_field
--
where:
[n] is the number of rows to be returned (row per page)
[m] is the ordinal position of the first row returned (0=return the first row, 1=return the 2 row, etc.).
gnicoli,
The only problem with this approach is that [n] and [m] have to be constants. This means that in a Stored Procedure the SQL Statement would have to be written as dynamic SQL.
Anthony
The only problem with this approach is that [n] and [m] have to be constants. This means that in a Stored Procedure the SQL Statement would have to be written as dynamic SQL.
Anthony
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
That is true. Set ROWCOUNT (unlike TOP) will allow a variable.
Anthony
Anthony
Also, you may find Experts more responsive if you took the time to re-read the EE Guidelines regarding grading standards. For the record:
Questions Asked 6
Last 10 Grades Given C D D B B
Question Grading Record 5 Answers Graded / 5 Answers Received
Anthony