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

SQL Server的等效语法是什么?


当前回答

您可以在公共表表达式中使用ROW_NUMBER来实现这一点。

;WITH My_CTE AS
(
     SELECT
          col1,
          col2,
          ROW_NUMBER() OVER(ORDER BY col1) AS row_number
     FROM
          My_Table
     WHERE
          <<<whatever>>>
)
SELECT
     col1,
     col2
FROM
     My_CTE
WHERE
     row_number BETWEEN @start_row AND @end_row

其他回答

select top (@TakeCount) * --FETCH NEXT
from(
    Select  ROW_NUMBER() OVER (order by StartDate) AS rowid,*
    From YourTable
)A
where Rowid>@SkipCount --OFFSET

特别是对于SQL-SERVER,您可以通过许多不同的方式实现这一点。对于给定的真实例子,我们取Customer表。

例1:使用"SET ROWCOUNT"

SET ROWCOUNT 10
SELECT CustomerID, CompanyName from Customers
ORDER BY CompanyName

若要返回所有行,请将ROWCOUNT设置为0

SET ROWCOUNT 0  
SELECT CustomerID, CompanyName from Customers
    ORDER BY CompanyName

例2:使用"ROW_NUMBER and OVER"

With Cust AS
( SELECT CustomerID, CompanyName,
ROW_NUMBER() OVER (order by CompanyName) as RowNumber 
FROM Customers )
select *
from Cust
Where RowNumber Between 0 and 10

例3:使用“OFFSET and FETCH”,但是使用这个“ORDER BY”是强制的

SELECT CustomerID, CompanyName FROM Customers
ORDER BY CompanyName
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY

希望这对你有所帮助。

在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 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是明确存在的

在SQL server中,你可以使用TOP和ROW_NUMBER()