ChatGPT解决这个技术问题 Extra ChatGPT

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

我一直在尝试了解如何在 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 功能实现为文章中的功能,但真的没有运气。

任何想法如何实现它?


R
Radim Köhler

在 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

(我宁愿将其标记为 hack - 但它已被使用,例如 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

非常感谢!这真是一个很好的答案!只有关于 sql 2008 的问题之一。我希望 ORDER BY 发生在 WHERE 之前,因为它目前会对子集进行排序,但我们想从整个集合中选择一些东西......有什么想法吗? :) 再一次,谢谢
如果我对您的理解正确,您希望按 LastDate 排序,对吗?然后我们可以这样更改 OVER() 子句:ROW_NUMBER() OVER (ORDER BY MAX(Datemade) desc)。并删除最后一个 ORDER BY PostId。现在 CTE 应该根据需要“尽快”排序。正确的?
谢谢你的帮助,关于 2012 示例的注释,order by 是强制性的,我在没有 order by 子句的情况下尝试这个并且得到错误“不正确的语法”直到我查看 MSDN 语法并了解到 order by 是强制性的之前不知道出了什么问题.
第一行是 1 还是 0?如果 @Start 为 0 且 @End 为 1000,WHERE 是否应为 WHERE RowNumber >= @Start AND RowNumber < @End 以获取前 1000 行?
@CWSpear,好吧,您可以自己尝试...但是 @start = 0 将占据第一行,而 @end = 1000 将意味着每页占据 1000 行。检查我使用的 WHERE 子句:WHERE RowNumber > @Start AND RowNumber <= @End
F
Felipe V. R.

为了在 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


N
Nicolas Sroczynski
OFFSET     10 ROWS       -- skip 10 rows
FETCH NEXT 10 ROWS ONLY; -- take 10 rows

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


T
Tadej

SQL 2008

Radim Kö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


S
Sheikh M. Haris

修复方法是使用 XML 编辑器修改您的 EDMX 文件,并将 ProviderManifestToken 的值从 2012 更改为 2008。我在 EDMX 文件的第 7 行发现了这一点。保存该更改后,将使用“旧”的 SQL Server 2008 兼容语法生成分页 SQL。

我很抱歉在这个非常古老的线程上发布答案。为像我这样的人发布它,我今天解决了这个问题。


我认为这不属于这里。问题是关于 SQL Server 查询,而您正在解释如何修改 Visual Studio 生成的文件以使用较旧的 SQL Server 实例。
A
Amin Golmahalle

您可以使用嵌套查询进行分页,如下所示:

从 4 行分页到 8 行,其中 CustomerId 是主键。

SELECT Top 5 * FROM Customers
WHERE Country='Germany' AND CustomerId Not in (SELECT Top 3 CustomerID FROM Customers
WHERE Country='Germany' order by city) 
order by city;