假设我使用的是Northwind数据库,并且希望通过包含其他参数的存储过程运行查询,以下:使用SQL Server 2005中的ROW_NUMBER()OVER()对不同列进行排序的分页查询
@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
我试着查询了几次,使用不同的参数,它的表现是相当不错的实际,但它剧照看起来像它可能被优化的一些其他的方式。
这个查询有什么问题,或者你会这样做吗?你提出一个不同的方法?
我的愚蠢的错误,修正了。请再试一次。 – Tomalak 2008-10-27 14:28:18