SQL Server的LIMIT和OFFSET的等价物?

在PostgreSQL里有LimitOffset关键字,这样可以非常方便地对结果集进行分页。

什么是Sql Server的等效语法?

LIMIT的等价物是SET ROWCOUNT ,但是如果你想要generics分页,最好这样写一个查询:

 ;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参数应该使用基于一的索引而不是正常的从零开始的索引。

这个function现在在SQL Server 2012中变得简单。这是工作,但SQL Server 2012起。 限制偏移量以在sql server中select11到20行:

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

//抵消 – 不。 跳过的行

//下一个 – 不需要 下一排

 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} 

注意:此解决scheme只能在SQL Server 2005或更高版本中使用,因为这是在执行ROW_NUMBER()发生的。

您可以在公用表expression式中使用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 

另一个样本:

 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; 

在这里有人告诉这个function在SQL 2011中,它的悲伤,他们select了一个不同的关键字“OFFSET / FETCH”,但它不是标准的,那么确定。

在Aaronaught的解决scheme上添加一个细微的变化,我通常参数化页码(@PageNum)和页面大小(@PageSize)。 这样,每个页面点击事件就会以请求的页码和可configuration的页面大小发送:

 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 * FROM( SELECT *, ROW_NUMBER() over (ORDER BY ID ) as ct from [db].[dbo].[table] ) sub where ct > fromNumber and ct <= toNumber 

我猜想类似于select * from [db].[dbo].[table] LIMIT 0, 10

 @nombre_row :nombre ligne par page @page:numero de la page //--------------code sql--------------- declare @page int,@nombre_row int; set @page='2'; set @nombre_row=5; SELECT * FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY etudiant_ID ) AS RowNum, * FROM etudiant ) AS RowConstrainedResult WHERE RowNum >= ((@page-1)*@nombre_row)+1 AND RowNum < ((@page)*@nombre_row)+1 ORDER BY RowNum 

由于没有人提供这个代码:

 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必须相同
  • 可以将@limitreplace为检索结果的数量,
  • @offset是跳过的结果数量
  • 请将性能与以前的解决scheme进行比较,因为它们可能更高效
  • 这个解决scheme复制whereorder by子句,如果它们不同步,将提供不正确的结果
  • 另一方面order by如果这是需要的,那么order by是明确的

对我来说,使用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对我不起作用。

 -- @RowsPerPage can be a fixed number and @PageNumber number can be passed DECLARE @RowsPerPage INT = 10, @PageNumber INT = 2 SELECT * FROM MemberEmployeeData ORDER BY EmployeeNumber OFFSET @PageNumber*@RowsPerPage ROWS FETCH NEXT 10 ROWS ONLY 

在SQL服务器中,您将使用TOP和ROW_NUMBER()

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

准备使用PHP和MSSQL 2008:

 $offset=($page-1)*$limit; $query = "SELECT {$field1},{$field1},{$field1},...,{$fieldN} FROM ( SELECT {$field1},{$field1},{$field1},...,{$fieldN}, ROW_NUMBER() OVER (ORDER BY {$orderField}) AS x FROM {$table} ) AS y WHERE yx BETWEEN ".$offset." AND ".($offset+$limit)." ORDER BY yx {$order};"; 

我喜欢微软如何在最复杂的情​​况下完成一件事情。 <3