在PostgreSQL中,有Limit和Offset关键字,可以非常容易地对结果集进行分页。

SQL Server的等效语法是什么?


当前回答

因为,我测试了更多次这个脚本更有用的100万条记录,每页100条记录分页工作更快,我的PC执行这个脚本0秒,而与mysql相比有自己的限制和偏移约4.5秒得到结果。

有些人可能不理解Row_Number()总是按特定字段排序。如果我们只需要按顺序定义行,应该使用:

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}

解释:

{LIMIT}:每页的记录数 {OFFSET}:跳过记录的个数

其他回答

在Aaronaught的解决方案的基础上增加了一点变化,我通常对页码(@PageNum)和页面大小(@PageSize)进行参数化。这样,每个页面点击事件只发送请求的页码和可配置的页面大小:

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

对我来说,一起使用OFFSET和FETCH很慢,所以我使用了TOP和OFFSET的组合,就像这样(这更快):

SELECT TOP 20 * FROM (SELECT columname1, columname2 FROM tablename
    WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname

注意:如果在同一个查询中同时使用TOP和OFFSET:

SELECT TOP 20 columname1, columname2 FROM tablename
    WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS

然后你会得到一个错误,所以为了同时使用TOP和OFFSET,你需要用子查询来分离它。

如果你需要使用SELECT DISTINCT,那么查询如下:

SELECT TOP 20 FROM (SELECT DISTINCT columname1, columname2
    WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname

注意:使用SELECT ROW_NUMBER和DISTINCT不适合我。

这里有人在sql 2011中讲述了这个功能,令人遗憾的是,他们选择了一个有点不同的关键字“OFFSET / FETCH”,但它不是标准的,然后ok。

另一个例子:

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;

这个特性现在在SQL Server 2012中变得很容易。 这是从SQL Server 2012开始工作的。

在SQL Server中限制偏移量为11到20行:

SELECT email FROM emailTable 
WHERE user_id=3
ORDER BY Id
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;

订购方式:必需 OFFSET:可选的跳过行数 NEXT:所需的下一行数

参考:https://learn.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql