分页的查询使用的排序在不同的列使用ROW_NUMBER()过()in SQL服务器2005年

StackOverflow https://stackoverflow.com/questions/230058

  •  04-07-2019
  •  | 
  •  

让我们假设我用罗斯文数据库和我谨运行查询通过存储的过程,包含,除其他参数,如下:

  • @Offset 表明那里的分页开始,
  • @Limit 表明页面尺寸,
  • @SortColumn 表明列用于排序的目的,
  • @SortDirection, ,以表明长辈或后代分类。

这个想法是做分页的数据库,作为结果设置包含了上千行如此缓存不是一个选项(和使用视图状态甚至不认为,海事组织,吸).

因为你可能知道SQL服务器2005年提供的功能 ROW_NUMBER返回的顺序号排分区内的一个结果是设置,开始在1的第一行,在每个分区.

我们需要排序上的每一个返回柱(五在这个例子)和动态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

我已经试过查询若干次,有不同的参数,其表现是相当不错实际上,但它的剧照看起来像它可能优化的其他一些方式。

是什么这个查询或者你会这样做?你提出一种不同的做法?

有帮助吗?

解决方案

简单:

SELECT
  OrderID, CustomerID, EmployeeID, OrderDate, ShippedDate,
  @Offset, @Limit, @SortColumn, @SortDirection
FROM
  Orders
WHERE
  ROW_NUMBER() OVER 
  (
    ORDER BY
      /* same expression as in the ORDER BY of the whole query */
  ) BETWEEN (@PageNum - 1) * @PageSize + 1 AND @PageNum * @PageSize 
  /* AND more conditions ... */
ORDER BY
  CASE WHEN @SortDirection = 'A' THEN
    CASE @SortColumn 
      WHEN 'OrderID'    THEN OrderID
      WHEN 'CustomerID' THEN CustomerID
      /* more... */
    END
  END,
  CASE WHEN @SortDirection = 'D' THEN
    CASE @SortColumn 
      WHEN 'OrderID'    THEN OrderID
      WHEN 'CustomerID' THEN CustomerID
      /* more... */
    END 
  END DESC

这将排序上NULL(DESC)如果委员会为选择,或反之亦然。

让ROW_NUMBER()function工作过的同样的顺序由表达。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top