在SQL Server 2008中微调/更正我的自定义分页

时间:2014-07-10 09:47:08

标签: sql sql-server tsql

目前我有tsql存储过程,它根据每个页面请求检索数据。我传入参数:PageIndex& PageSize如下:

@ColNames VARCHAR(1000), @PageIndex INT = 1, @PageSize INT = 100

DECLARE @s_query VARCHAR(MAX);
DECLARE @RecordCount INT;

SET @s_query = 
'Select ROW_NUMBER() OVER (ORDER BY ' + @ColNames + ') AS ##RowNum, '+@ColNames+' INTO ##Results' +
' FROM Table1 U
Inner Join Date D on U.DateID = D.DateID            
ORDER BY D.DateID DESC';

EXEC (@s_query);

SET @s_query =  
'SELECT ' + @ColNames + ' FROM ##Results
WHERE ##RowNum BETWEEN('+CONVERT(varchar(20),@PageIndex)+'-1) * '+CONVERT(varchar(20),@PageSize)+' + 1 
AND((('+CONVERT(varchar(20),@PageIndex)+' -1) * '+CONVERT(varchar(20),@PageSize)+' + 1) + '+CONVERT(varchar(20),@PageSize)+') - 1';

EXEC (@s_query);

以上工作正常,但我的问题/问题是:返回的结果(100行)没有按日期排序,就像上面的第一个s_query一样。我需要按日期排序结果。我猜在第二个查询中我选择的是pagesize结果,它是随机进行的。有人能指出我的错。

2 个答案:

答案 0 :(得分:1)

您应该在ROW_NUMBER部分中设置排序。在第一个查询中也没有必要应用查询排序(删除结束ORDER BY,排序已经由ROW_NUMBER函数完成,您应该在第二个查询中按此列排序以对您的分页应用正确的排序)。

更正后的代码:

DECLARE @ColNames VARCHAR(1000), @PageIndex INT = 1, @PageSize INT = 100

DECLARE @s_query VARCHAR(MAX);
DECLARE @RecordCount INT;


SET @s_query = 
'Select ROW_NUMBER() OVER (ORDER BY D.DateID DESC) AS RowNum, '+@ColNames+' INTO ##Results ' +
'FROM Table1 U ' +
'Inner Join Date D on U.DateID = D.DateID';

EXEC (@s_query);

SET @s_query =  
'SELECT ' + @ColNames + ' FROM ##Results ' +
'WHERE RowNum BETWEEN ('+ CAST((@PageIndex-1)*@PageSize+1 AS nvarchar(20)) + ' AND ' + CAST(@PageIndex*@PageSize AS nvarchar(20)) + ') ' +
'ORDER BY RowNum ';

EXEC (@s_query);

优化代码(不需要使用临时表,也不需要加入日期表):

DECLARE @ColNames VARCHAR(1000), @PageIndex INT = 1, @PageSize INT = 100

DECLARE @s_query VARCHAR(MAX);
DECLARE @RecordCount INT;


SET @s_query = 
'
WITH cte AS 
(
    SELECT
        ROW_NUMBER() OVER (ORDER BY DateID DESC) AS RowNum
        , ' + @ColNames + ' 
    FROM 
        Table1
)

SELECT
    ' + @ColNames + '
    ,TotalRowCount = (SELECT COUNT(*) FROM Table1)
FROM
    cte
WHERE
    RowNum BETWEEN ('+ CAST((@PageIndex-1)*@PageSize+1 AS nvarchar(20)) + ' AND ' + CAST(@PageIndex*@PageSize AS nvarchar(20)) + ') 
ORDER BY
    RowNum 
';

EXEC (@s_query);

答案 1 :(得分:0)

除了order by子句指定的SQL数据之外,SQL数据没有任何顺序。

在第二个查询的末尾添加order by子句,指定所需的顺序。

第一个查询中的order by子句什么都不做,所以你也可以删除它。