在SQL Server 2005和2008中从复杂查询中分页结果的最佳方法是什么?
我想出了以下方法:
执行查询,将其结果保存到表变量或临时表中。
使用以下代码:
DECLARE @Rows INT = (SELECT COUNT(*) FROM @TableVariable)
DELETE TV
FROM @TableVariable TV
JOIN (SELECT TV2.PrimaryKey, ROW_NUMBER() OVER(...) AS RowNo
FROM @TableVariable TV2) N ON TV.PrimaryKey = TV2.PrimaryKey
WHERE N.RowNo < @FromRow OR N.RowNo > @ToRow
SELECT PrimaryKey, SomeComputedField, ...
FROM @TableVariable
RETURN @Rows
但是,我自己没有任何分享庞大数据集的经验。其他SOers有什么建议?
答案 0 :(得分:2)
存储程序正文可以写成:
;WITH rownums AS (
SELECT tempTable.[link],
ROW_NUMBER() OVER (ORDER BY tempTable.[link]) AS rownum
FROM <temptable here> AS tempTable
)
SELECT tempTable.link
FROM <temptable here> AS tempTable
INNER JOIN rownums AS rn
ON rn.[link] = drn.[link]
WHERE rn.[rownum] BETWEEN @low AND @high
然后你需要提供带有范围(@low和@high)的STORED PROCEDURE,你当然需要临时表。
P.S。另外,我认为你的变量声明只适用于2008年,如果我没记错的话,2005年不支持单行实例化和初始化。
答案 1 :(得分:1)
如果您的数据集很大,@ table将无法正常运行。你的row_number也可以稍微优化一下,不要超过@ToRow
JOIN (SELECT TOP(@ToRow) TV2.PrimaryKey, ROW_NUMBER() OVER(...) AS RowNo
FROM @TableVariable TV2
ORDER BY ... -- same clause as ROW_NUMBER()
我会走下Stored Proc的路线,填充#table(使用TOP如上所示),同时使用IDENTITY(int,1,1)SELECT INTO或预先创建表格一个标识(clustered),然后代替DELETE然后SELECT(2 ops),只需从#temptable中选择
WHERE id-column between x and y