存储过程和使用排序和过滤进行分页

时间:2014-09-16 18:04:30

标签: sql-server sql-server-2008

我在表中有数据并编写了一个很好的存储过程,它有一个CTE并且可以很好地进行分页。

我现在有一个请求能够通过给定的列名和特定方向(ASC / DESC)进行排序 - 这不是一个问题,但它似乎只对那个页面执行奇怪的排序/排序它只对它返回的结果集进行排序,而不是按正确的排序顺序排列当前页面。

以下是存储过程代码:

CREATE PROCEDURE [dbo].[sp_GetProducts] (
    @itemsPerPage int,
    @pageNumber int,
    @totalRecords int OUTPUT,   
    @sortByFieldName nvarchar(30) = 'ID',
    @sortDir nvarchar(5) = 'ASC'
)
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @firstRow int
    DECLARE @lastRow int

    SELECT 
       @firstRow = (@pageNumber - 1) * @itemsPerPage + 1,
       @lastRow = (@pageNumber - 1) * @itemsPerPage + @itemsPerPage,
       @totalRecords = (SELECT COUNT(p.[SDSID]) FROM v_SDS_Summary p);

    WITH ProductSummary AS
    (
        SELECT 
           p.[ID], p.Product, p.SecondName, p.Manufacturer, p.Category,
           ROW_NUMBER() OVER (ORDER BY p.ID ASC) AS RowNumber
        FROM v_Product_Summary p
    )
    SELECT 
       RowNumber, [ID], Product, SecondName, Manufacturer, Category
    FROM 
       ProductSummary 
    WHERE 
       RowNumber BETWEEN @firstRow AND @lastRow
    ORDER BY 
       --SDSID ASC
       CASE @sortByFieldName
           WHEN 'ID' THEN CAST(ID as varchar(50))
           WHEN 'Product' THEN Product
           WHEN 'CommonName' THEN SECONDNAME
           WHEN 'Manufacturer' THEN MANUFACTURER
           WHEN 'Category' THEN CATEGORY
       END
END

当我运行它并给它一个页码时,它会带来很好的结果。

当我告诉它我希望按列名排序时,它似乎以一种我甚至无法描述的奇怪方式对其进行排序。基本上似乎有些人只是从a-z

来压缩该页面上的排序

Sorting issue

所以在这里,这是按ASC中的Product排序的,但正如您所看到的,排序不正确。从技术上讲,它似乎是分类的,但这些并不是DB中唯一的产品。大约有3,000种产品,肯定会成为" a"或" b"产品将在我指定的第2页上显示。

我做错了什么?

1 个答案:

答案 0 :(得分:1)

您的CTE始终按ID排序,因此它始终使用它来获取Page:

WITH ProductSummary AS
(
    SELECT p.[ID], p.Product, p.SecondName, p.Manufacturer, p.Category,
    ROW_NUMBER() OVER (ORDER BY p.ID ASC) AS RowNumber
    FROM v_Product_Summary p
)

然后在页面上,您将使用以下内容对结果页面进行排序:

ORDER BY --SDSID ASC
CASE @sortByFieldName
    WHEN 'ID' THEN CAST(ID as varchar(50))
    WHEN 'Product' THEN Product
    WHEN 'CommonName' THEN SECONDNAME
    WHEN 'Manufacturer' THEN MANUFACTURER
    WHEN 'Category' THEN CATEGORY
END

您应该在CTE中使用相同的ORDER BY来真正按该列排序所有结果:

WITH ProductSummary AS
(
    SELECT p.[ID], p.Product, p.SecondName, p.Manufacturer, p.Category,
    ROW_NUMBER() OVER (ORDER BY CASE @sortByFieldName
        WHEN 'ID' THEN CAST(ID as varchar(50))
        WHEN 'Product' THEN Product
        WHEN 'CommonName' THEN SECONDNAME
        WHEN 'Manufacturer' THEN MANUFACTURER
        WHEN 'Category' THEN CATEGORY
END ASC) AS RowNumber
    FROM v_Product_Summary p
)