使用此查询实现分页(跳过/获取)功能

时间:2012-11-04 17:00:54

标签: sql sql-server join pagination

我一直试图了解如何在SQL中实现自定义分页,例如阅读articles like this one

我有以下查询,它完美无缺。但我想用这个实现分页。

SELECT TOP x PostId FROM ( SELECT PostId, MAX (Datemade) as LastDate
 from dbForumEntry 
 group by PostId ) SubQueryAlias
 order by LastDate desc

我想要的是什么

我有论坛帖子,有相关条目。我想获得最新添加条目的帖子,所以我可以选择最近讨论的帖子。

现在,我希望能够获得“最近10到20个活跃的帖子”,而不是“前10名”。

我尝试了什么

我试图将ROW函数实现为文章中的那个,但实际上没有运气。

任何想法如何实现它?

6 个答案:

答案 0 :(得分:231)

SQL Server 2012 中,这非常容易

SELECT col1, col2, ...
 FROM ...
 WHERE ... 
 ORDER BY -- this is a MUST there must be ORDER BY statement
-- the paging comes here
OFFSET     10 ROWS       -- skip 10 rows
FETCH NEXT 10 ROWS ONLY; -- take 10 rows

如果我们想跳过ORDER BY,我们可以使用

SELECT col1, col2, ...
  ...
 ORDER BY CURRENT_TIMESTAMP
OFFSET     10 ROWS       -- skip 10 rows
FETCH NEXT 10 ROWS ONLY; -- take 10 rows

(我宁愿将其标记为黑客 - 但它已被使用,例如NHibernate。使用明智的选择列作为ORDER BY是首选方式)

回答这个问题:

--SQL SERVER 2012
SELECT PostId FROM 
        ( SELECT PostId, MAX (Datemade) as LastDate
            from dbForumEntry 
            group by PostId 
        ) SubQueryAlias
 order by LastDate desc
OFFSET 10 ROWS -- skip 10 rows
FETCH NEXT 10 ROWS ONLY; -- take 10 rows

引入了新的关键字offsetfetch next(仅遵循SQL标准)。

但我想,你没有使用 SQL Server 2012 ,对吧?在以前的版本中,它有点(一点点)困难。以下是所有SQL Server版本的比较和示例:here

因此,这可以在 SQL Server 2008

中使用
-- SQL SERVER 2008
DECLARE @Start INT
DECLARE @End INT
SELECT @Start = 10,@End = 20;


;WITH PostCTE AS 
 ( SELECT PostId, MAX (Datemade) as LastDate
   ,ROW_NUMBER() OVER (ORDER BY PostId) AS RowNumber
   from dbForumEntry 
   group by PostId 
 )
SELECT PostId, LastDate
FROM PostCTE
WHERE RowNumber > @Start AND RowNumber <= @End
ORDER BY PostId

答案 1 :(得分:5)

为了在SQL Server中执行此操作,您必须按列排序查询,以便指定所需的行。

示例:

select * from table order by [some_column] 
offset 10 rows
FETCH NEXT 10 rows only

执行此操作时,您无法使用“TOP”关键字。

您可以在此处了解详情: https://technet.microsoft.com/pt-br/library/gg699618%28v=sql.110%29.aspx

答案 2 :(得分:2)

SQL 2008

RadimKöhler的答案有效,但这是一个较短的版本:

select top 20 * from
(
select *,
ROW_NUMBER() OVER (ORDER BY columnid) AS ROW_NUM
from tablename
) x
where ROW_NUM>10

来源:https://forums.asp.net/post/4033909.aspx

答案 3 :(得分:1)

OFFSET     10 ROWS       -- skip 10 rows
FETCH NEXT 10 ROWS ONLY; -- take 10 rows

在选择语法的末尾使用它。 =)

答案 4 :(得分:0)

您可以使用嵌套查询进行分页,如下所示: 从4行到8行进行分页,其中CustomerId是主键

从客户中选择前5名* 国家/地区=&#39;德国&#39; AND CustomerId不在(从客户中选择前3个客户ID) 国家/地区=&#39;德国&#39;按城市排序) 按城市排序;

答案 5 :(得分:0)

解决方法是使用XML编辑器修改EDMX文件,并将 ProviderManifestToken 的值从 2012 更改为 2008 。我在EDMX文件的第7行中找到了它。保存更改后,将使用“旧的” SQL Server 2008兼容语法生成分页SQL。

我很抱歉在这个非常旧的主题上发布答案。将其发布给像我这样的人,我今天解决了这个问题。