我可以在不使用 ROW_NUM () OVER (ORDER BY xxxxx) 的情况下在 Sql Server 中对查询进行分页吗?
Posted
技术标签:
【中文标题】我可以在不使用 ROW_NUM () OVER (ORDER BY xxxxx) 的情况下在 Sql Server 中对查询进行分页吗?【英文标题】:Can I paginate a query in Sql Server without using ROW_NUM () OVER (ORDER BY xxxxx)? 【发布时间】:2012-01-25 04:08:08 【问题描述】:我正在开发自定义 DAL,现在正在处理自动结果分页。 DAL 根据我们的模型生成动态查询,例如:
Model.All() --> generates "select * from mytable"
Model.Filter ("d=@0", "arg0value") --> generates "select * from mytable where d=@0"
...
我不想为我们的过滤函数添加额外的参数,也不想为分页添加专门的函数(当然,如果可以避免的话)。相反,我想对结果进行分页更改查询之前它被执行。比如……
var resultset = Model.Filter ("d=@0, "arg0value"); // "select * from mytable where d=@0"
resulset = resultset.Paginate (1, 25); // this should paginate the query before loading any objects
在 Oracle 中,使用 ROWNUM 伪列并包装旧查询很容易。
select * from (my old sql) where rownum between 20 and 40
在 Sql Server (2005) 中没有像 ROWNUM 这样的东西。我已经看到有 ROW_NUMBER 函数,但它需要知道查询的内部,因为您需要传递“OVER (ORDER BY xxxx)”子句。
select row_number() over (order By <?????>) as rownum, dv.* from (my old sql) as dv where rownum between 20 and 40
那么,有没有一种方法可以在 Sql Server 中执行此操作,而无需向我们的模型添加特定的参数/函数?
谢谢!
编辑
正如@Dems 所说,我可以解析查询并根据输出字段添加 ORDER BY,但是:首先,我不想要解析的开销,其次,如果查询的类型为“select * ",我无法提取字段。
【问题讨论】:
在 SQL Server 2012 中,将有 OFFSET and FETCH NEXT - 但在那之前,带有ROW_NUMBER()
的 CTE 是您唯一真正可行的选择...
【参考方案1】:
如果您正在编写自己的数据访问层,并且您想应用 ROW_NUMBER() 只知道查询的输出字段名称(而不是它的内部)...
SELECT
*
FROM
(
SELECT
ROW_NUMBER() OVER (ORDER BY field1, field2, field3) AS row_id,
*
FROM
(
<your-query>
)
AS unordered_data
)
AS ordered_data
WHERE
row_id BETWEEN x AND y
【讨论】:
感谢您的回答,但如果上一个查询是“select * ...”,我无法提取字段。我已更新问题以反映这一点。 那么您唯一可用的选项是控制在您的客户端中提取的记录,可能使用记录集。这可用于避免拉取不必要记录的网络流量,但不会为您的 SQL Server 节省任何负载。 看来我必须添加一些特定的功能,这样我才能在查询生成期间使用模型元数据。我等会儿。如果没有更好的答案,我会接受这个,因为有见地。谢谢。以上是关于我可以在不使用 ROW_NUM () OVER (ORDER BY xxxxx) 的情况下在 Sql Server 中对查询进行分页吗?的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server 可以在不使用 cte 的情况下根据排名限制查询结果吗?