假設我使用的是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