【发布时间】:2010-09-18 19:21:44
【问题描述】:
假设我正在使用 Northwind 数据库,并且我想通过包含以下参数的存储过程运行查询:
-
@Offset表示分页从哪里开始, -
@Limit表示页面大小, -
@SortColumn表示用于排序的列, -
@SortDirection,表示升序或降序。
这个想法是在数据库上进行分页,因为结果集包含数千行,所以缓存不是一种选择(而且使用 VIEWSTATE 甚至不被认为是,IMO,很烂)。
您可能知道,SQL Server 2005 提供了函数ROW_NUMBER,它返回结果集分区内行的序号,每个分区的第一行从 1 开始。
我们需要对每个返回的列(本例中为 5 个)进行排序,动态 SQL 不是一个选项,因此我们有两种可能性:使用大量 IF ... ELSE ... 并有 10 个查询,这很难维护,或者有如下查询:
WITH PaginatedOrders AS (
SELECT
CASE (@SortColumn + ':' + @SortDirection)
WHEN 'OrderID:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.OrderID ASC)
WHEN 'OrderID:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.OrderID DESC)
WHEN 'CustomerID:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.CustomerID ASC)
WHEN 'CustomerID:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.CustomerID DESC)
WHEN 'EmployeeID:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.EmployeeID ASC)
WHEN 'EmployeeID:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.EmployeeID DESC)
WHEN 'OrderDate:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.OrderDate ASC)
WHEN 'OrderDate:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.OrderDate DESC)
WHEN 'ShippedDate:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.OrderID ASC)
WHEN 'ShippedDate:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.OrderID DESC)
END AS RowNumber,
OrderID, CustomerID, EmployeeID, OrderDate, ShippedDate
FROM Orders
-- WHERE clause goes here
)
SELECT
RowNumber, OrderID, CustomerID, EmployeeID, OrderDate, ShippedDate,
@Offset, @Limit, @SortColumn, @SortDirection
FROM PaginatedOrders
WHERE RowNumber BETWEEN @Offset AND (@Offset + @Limit - 1)
ORDER BY RowNumber
我已经多次尝试查询,使用不同的参数,它的性能实际上是相当不错的,但它仍然看起来可能会以其他方式进行优化。
这个查询有什么问题,或者你会这样做吗?您是否提出了不同的方法?
【问题讨论】:
-
我的愚蠢错误,已修复。请重试。
标签: sql-server-2005 pagination