Row Offset in SQL Server

后端 未结 16 2379
醉酒成梦
醉酒成梦 2020-11-22 05:53

Is there any way in SQL Server to get the results starting at a given offset? For example, in another type of SQL database, it\'s possible to do:

SELECT * FR         


        
相关标签:
16条回答
  • 2020-11-22 06:17

    There is OFFSET .. FETCH in SQL Server 2012, but you will need to specify an ORDER BY column.

    If you really don't have any explicit column that you could pass as an ORDER BY column (as others have suggested), then you can use this trick:

    SELECT * FROM MyTable 
    ORDER BY @@VERSION 
    OFFSET 50 ROWS FETCH NEXT 25 ROWS ONLY
    

    ... or

    SELECT * FROM MyTable 
    ORDER BY (SELECT 0)
    OFFSET 50 ROWS FETCH NEXT 25 ROWS ONLY
    

    We're using it in jOOQ when users do not explicitly specify an order. This will then produce pretty random ordering without any additional costs.

    0 讨论(0)
  • 2020-11-22 06:21

    I use this technique for pagination. I do not fetch all the rows. For example, if my page needs to display the top 100 rows I fetch only the 100 with where clause. The output of the SQL should have a unique key.

    The table has the following:

    ID, KeyId, Rank
    

    The same rank will be assigned for more than one KeyId.

    SQL is select top 2 * from Table1 where Rank >= @Rank and ID > @Id

    For the first time I pass 0 for both. The second time pass 1 & 14. 3rd time pass 2 and 6....

    The value of the 10th record Rank & Id is passed to the next

    11  21  1
    14  22  1
    7   11  1
    6   19  2
    12  31  2
    13  18  2
    

    This will have the least stress on the system

    0 讨论(0)
  • 2020-11-22 06:23

    You can use ROW_NUMBER() function to get what you want:

    SELECT *
    FROM (SELECT ROW_NUMBER() OVER(ORDER BY id) RowNr, id FROM tbl) t
    WHERE RowNr BETWEEN 10 AND 20
    
    0 讨论(0)
  • 2020-11-22 06:24

    This is one way (SQL2000)

    SELECT * FROM
    (
        SELECT TOP (@pageSize) * FROM
        (
            SELECT TOP (@pageNumber * @pageSize) *
            FROM tableName 
            ORDER BY columnName ASC
        ) AS t1 
        ORDER BY columnName DESC
    ) AS t2 
    ORDER BY columnName ASC
    

    and this is another way (SQL 2005)

    ;WITH results AS (
        SELECT 
            rowNo = ROW_NUMBER() OVER( ORDER BY columnName ASC )
            , *
        FROM tableName 
    ) 
    SELECT * 
    FROM results
    WHERE rowNo between (@pageNumber-1)*@pageSize+1 and @pageNumber*@pageSize
    
    0 讨论(0)
  • 2020-11-22 06:25

    Following will display 25 records excluding first 50 records works in SQL Server 2012.

    SELECT * FROM MyTable ORDER BY ID OFFSET 50 ROWS FETCH NEXT 25 ROWS ONLY;
    

    you can replace ID as your requirement

    0 讨论(0)
  • 2020-11-22 06:29

    If you will be processing all pages in order then simply remembering the last key value seen on the previous page and using TOP (25) ... WHERE Key > @last_key ORDER BY Key can be the best performing method if suitable indexes exist to allow this to be seeked efficiently - or an API cursor if they don't.

    For selecting an arbitary page the best solution for SQL Server 2005 - 2008 R2 is probably ROW_NUMBER and BETWEEN

    For SQL Server 2012+ you can use the enhanced ORDER BY clause for this need.

    SELECT  *
    FROM     MyTable 
    ORDER BY OrderingColumn ASC 
    OFFSET  50 ROWS 
    FETCH NEXT 25 ROWS ONLY 
    

    Though it remains to be seen how well performing this option will be.

    0 讨论(0)
提交回复
热议问题