用于分页的T-SQL动态Order By in Common Table

Rob*_*Rob 4 t-sql pagination dynamic-sql common-table-expression

我发现了一些用于动态排序和订单的优秀sql代码,但我想知道是否有人可以帮我重新设置它以便下面PROC中的CTE使用动态排序/顺序.此代码运行 - 但输出不是我所追求的,因为ORDER BY p.ProductId首先在CTE中发生,然后ORDER BY CASE语句仅适用于记录6到10

DECLARE @Skip int
DECLARE @Take int
DECLARE @OrderBy VARCHAR(50)

SET @Skip = 5;
SET @Take = 5;
SET @OrderBy = 'PriceAsc';


WITH ProductCT AS
(
    SELECT ROW_NUMBER() OVER(ORDER BY p.ProductId) AS RowNum
    , p.ProductId
    FROM dbo.Product AS p
)
SELECT   p.ProductId
        ,p.Title
        ,p.Price
FROM dbo.Product AS p
INNER JOIN ProductCT AS pct ON pct.ProductId = p.ProductId
WHERE pct.RowNum BETWEEN @Skip + 1 AND (@Skip + @Take)
ORDER BY
    CASE     
         WHEN @OrderBy = 'TitleAsc' THEN (RANK() OVER (ORDER BY p.Title))
         WHEN @OrderBy = 'TitleDesc' THEN (RANK() OVER (ORDER BY p.Title DESC))
         WHEN @OrderBy = 'PriceAsc' THEN (RANK() OVER (ORDER BY p.Price))
         WHEN @OrderBy = 'PriceDesc' THEN (RANK() OVER (ORDER BY p.Price DESC))
         ELSE (RANK() OVER (ORDER BY p.Price))
    END
Run Code Online (Sandbox Code Playgroud)

在此先感谢您的任何建议 :-)

Rob*_*Rob 10

我最初将@Johan的答案标记为正确,因为它有效,但我对INNER JOIN以及此查询的整体复杂性有点不确定.

我和我的同事聊了聊这个问题,他提出了这个非常整洁的解决方案(谢谢汤姆!!)所以我想我会分享它:

DECLARE @Skip int
DECLARE @Take int
DECLARE @OrderBy VARCHAR(50)

SET @Skip = 5;
SET @Take = 5;
SET @OrderBy = 'PriceAsc';


WITH ProductCT AS
(
    SELECT
    CASE
       WHEN @OrderBy = 'TitleAsc' THEN ROW_NUMBER() OVER (ORDER BY p.Title)
       WHEN @OrderBy = 'TitleDesc' THEN ROW_NUMBER() OVER (ORDER BY p.Title DESC)
       WHEN @OrderBy = 'PriceAsc' THEN ROW_NUMBER() OVER (ORDER BY p.Price)
       WHEN @OrderBy = 'PriceDesc' THEN ROW_NUMBER() OVER (ORDER BY p.Price DESC)
    END AS RowNum
    , p.ProductId
    FROM dbo.Product AS p
)
SELECT   p.ProductId
        ,p.Title
        ,p.Price
FROM dbo.Product AS p
INNER JOIN ProductCT AS pct ON pct.ProductId = p.ProductId
WHERE pct.RowNum BETWEEN @Skip + 1 AND (@Skip + @Take)
ORDER BY RowNum
Run Code Online (Sandbox Code Playgroud)