Equivalent of LIMIT and OFFSET for SQL Server?

前端 未结 16 1936
天命终不由人
天命终不由人 2020-11-22 06:07

In PostgreSQL there is the Limit and Offset keywords which will allow very easy pagination of result sets.

What is the equivalent syntax f

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

    Since nobody provided this code yet:

    SELECT TOP @limit f1, f2, f3...
    FROM t1
    WHERE c1 = v1, c2 > v2...
    AND
        t1.id NOT IN
            (SELECT TOP @offset id
             FROM t1
             WHERE c1 = v1, c2 > v2...
             ORDER BY o1, o2...)
    ORDER BY o1, o2...
    

    Important points:

    • ORDER BY must be identical
    • @limit can be replaced with number of results to retrieve,
    • @offset is number of results to skip
    • Please compare performance with previous solutions as they may be more efficient
    • this solution duplicates where and order by clauses, and will provide incorrect results if they are out of sync
    • on the other hand order by is there explicitly if that's what's needed
    0 讨论(0)
  • 2020-11-22 06:45
    select top (@TakeCount) * --FETCH NEXT
    from(
        Select  ROW_NUMBER() OVER (order by StartDate) AS rowid,*
        From YourTable
    )A
    where Rowid>@SkipCount --OFFSET
    
    0 讨论(0)
  • 2020-11-22 06:47
    select top {LIMIT HERE} * from (
          select *, ROW_NUMBER() over (order by {ORDER FIELD}) as r_n_n 
          from {YOUR TABLES} where {OTHER OPTIONAL FILTERS}
    ) xx where r_n_n >={OFFSET HERE}
    

    A note: This solution will only work in SQL Server 2005 or above, since this was when ROW_NUMBER() was implemented.

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

    Another sample :

    declare @limit int 
    declare @offset int 
    set @offset = 2;
    set @limit = 20;
    declare @count int
    declare @idxini int 
    declare @idxfim int 
    select @idxfim = @offset * @limit
    select @idxini = @idxfim - (@limit-1);
    WITH paging AS
        (
            SELECT 
                 ROW_NUMBER() OVER (order by object_id) AS rowid, *
            FROM 
                sys.objects 
        )
    select *
        from 
            (select COUNT(1) as rowqtd from paging) qtd, 
                paging 
        where 
            rowid between @idxini and @idxfim
        order by 
            rowid;
    
    0 讨论(0)
  • 2020-11-22 06:48

    Adding a slight variation on Aaronaught's solution, I typically parametrize page number (@PageNum) and page size (@PageSize). This way each page click event just sends in the requested page number along with a configurable page size:

    begin
        with My_CTE  as
        (
             SELECT col1,
                  ROW_NUMBER() OVER(ORDER BY col1) AS row_number
         FROM
              My_Table
         WHERE
              <<<whatever>>>
        )
        select * from My_CTE
                WHERE RowNum BETWEEN (@PageNum - 1) * (@PageSize + 1) 
                                  AND @PageNum * @PageSize
    
    end
    
    0 讨论(0)
  • 2020-11-22 06:48

    Since, I test more times this script more useful by 1 million records each page 100 records with pagination work faster my PC execute this script 0 sec while compare with mysql have own limit and offset about 4.5 sec to get the result.

    Someone may miss understanding Row_Number() always sort by specific field. In case we need to define only row in sequence should use:

    ROW_NUMBER() OVER (ORDER BY (SELECT NULL))

    SELECT TOP {LIMIT} * FROM (
          SELECT TOP {LIMIT} + {OFFSET} ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS ROW_NO,*
          FROM  {TABLE_NAME}
    ) XX WHERE ROW_NO > {OFFSET}
    

    Explain:

    • {LIMIT}: Number of records for each page
    • {OFFSET}: Number of skip records
    0 讨论(0)
提交回复
热议问题