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

SQL Server的等效语法是什么?


当前回答

在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

其他回答

因为,我测试了更多次这个脚本更有用的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
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}

注意: 这个解决方案只能在SQL Server 2005或更高版本中工作,因为这是实现ROW_NUMBER()的时候。

因为还没有人提供这个代码:

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...

重要的几点:

ORDER BY必须相同 @limit可以替换为检索结果的数量, @offset是要跳过的结果数 请将性能与以前的解决方案进行比较,因为它们可能更有效 这个解决方案重复了where和order by子句,如果它们不同步,将提供不正确的结果 另一方面,如果需要的话,order by是明确存在的

LIMIT的等效函数是SET ROWCOUNT,但是如果你想要通用的分页,最好这样写一个查询:

;WITH Results_CTE AS
(
    SELECT
        Col1, Col2, ...,
        ROW_NUMBER() OVER (ORDER BY SortCol1, SortCol2, ...) AS RowNum
    FROM Table
    WHERE <whatever>
)
SELECT *
FROM Results_CTE
WHERE RowNum >= @Offset
AND RowNum < @Offset + @Limit

这里的优点是,如果您决定更改分页选项(或允许用户这样做),则可以将偏移量和限制参数化。

注意:@Offset参数应该使用基于1的索引,而不是普通的基于0的索引。