我在表中有数据,并编写了一个很好的存储过程,它具有 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
所以在这里,这是按 ASC 中的产品排序的,但正如您所看到的,排序不正确。从技术上讲,它似乎已排序,但这些并不是数据库中唯一的产品。大约有 3,000 种产品,按照我的指定,“a”或“b”产品肯定会显示在第 2 页上。
我做错了什么?
您的 CTE 始终按 ID 排序,因此它将始终使用 ID 来获取页面:
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
)
虽然这是一个很老的问题,但我想添加以下内容:
要使排序方向发挥作用,只需添加另一个具有排序方向的案例,而无需按照上述答案中的建议更改 CTE。
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
*
CASE @sortDir
WHEN 'DESC' THEN -1
ELSE 1
END