在PostgreSQL中,有Limit
和Offset
个关键字,可以非常轻松地对结果集进行分页。
Sql Server的等效语法是什么?
答案 0 :(得分:199)
此功能现在在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
:所需的下一行数量答案 1 :(得分:131)
相当于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
参数应该为此使用基于索引的索引而不是正常的从零开始索引。
答案 2 :(得分:23)
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()
实施的时候。
答案 3 :(得分:11)
您可以在公用表表达式中使用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
答案 4 :(得分:3)
对我来说,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
注意:使用带有DISTINCT的SELECT ROW_NUMBER对我不起作用。
答案 5 :(得分:2)
另一个样本:
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;
答案 6 :(得分:2)
有人here有人在sql 2011中讲述了这个功能,很遗憾他们选择了一个不同的关键字“OFFSET / FETCH”,但它不是标准然后确定。
答案 7 :(得分:2)
在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
答案 8 :(得分:2)
我能做的最接近的是
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
答案 9 :(得分:2)
-- @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
答案 10 :(得分:1)
select top (@TakeCount) * --FETCH NEXT
from(
Select ROW_NUMBER() OVER (order by StartDate) AS rowid,*
From YourTable
)A
where Rowid>@SkipCount --OFFSET
答案 11 :(得分:1)
@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
答案 12 :(得分:1)
由于还没有人提供此代码:
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...
重点:
@limit
可以替换为要检索的结果数量,@offset
是要跳过的结果数where
和order by
条款,如果不同步则会提供错误的结果order by
是明确的,如果那是需要的话答案 13 :(得分:0)
在SQL Server中,您将使用TOP和ROW_NUMBER()
答案 14 :(得分:0)
特别是对于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和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
希望这对您有所帮助。
答案 15 :(得分:-1)
自此,我测试了该脚本更多次,使每页100万条记录更有用。100条具有分页功能的记录更快,我的PC执行此脚本0秒,而与mysql比较则有自己的限制,并且偏移了4.5秒才能得到结果。
有些人可能会错过了解Row_Number()始终按特定字段排序的知识。如果只需要按顺序定义行,则应使用:
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}
说明: