【问题标题】:Dynamic Order by and sort by column [duplicate]动态排序并按列排序[重复]
【发布时间】:2018-12-06 19:23:27
【问题描述】:

我必须在 UI 网格中显示数据,并从 SQL Server 2014 中的两个不同表中选择数据。

数据可以按来自 UI 代码的任何列进行排序,并且可以按双向(ASC/DESC)进行排序。 UI 代码也传递方向。

在我当前的实现中,我们使用如下 CTE -

    ;WITH cte AS
    (SELECT ED.JobExecutionID
        , ED.RowNumber
        , ED.ErrorMessage
        , ED.RowData    
        , CASE 
            WHEN @SortKey = 'RowNumber' AND @SortDirection = 'Ascending' THEN ROW_NUMBER() OVER (ORDER BY ED.RowNumber ASC)
            WHEN @SortKey = 'RowNumber' AND @SortDirection = 'Descending' THEN ROW_NUMBER() OVER (ORDER BY ED.RowNumber DESC)
            WHEN @SortKey = 'ErrorMessage' AND @SortDirection = 'Ascending' THEN ROW_NUMBER() OVER (ORDER BY ED.ErrorMessage ASC)
            WHEN @SortKey = 'ErrorMessage' AND @SortDirection = 'Descending' THEN ROW_NUMBER() OVER (ORDER BY ED.ErrorMessage DESC)
            WHEN @SortKey = 'RowData' AND @SortDirection = 'Ascending' THEN ROW_NUMBER() OVER (ORDER BY ED.RowData ASC)
            WHEN @SortKey = 'RowData' AND @SortDirection = 'Descending' THEN ROW_NUMBER() OVER (ORDER BY ED.RowData DESC)
            ELSE ROW_NUMBER() OVER (ORDER BY  ED.RowNumber ASC)
         END AS SortRowNumber       
    FROM ExceptionDetails ED        
    JOIN ExecutionDetails IED ON IED.JobExecutionID = ED.JobExecutionID
    WHERE ED.JobExecutionID = @JobExecutionId
),
RESULTS AS  
    (SELECT * FROM cte) 
SELECT JobExecutionID
    , RowNumber
    , ErrorMessage
    , RowData
    , SortRowNumber
FROM RESULTS
WHERE SortRowNumber BETWEEN @StartRowNumber AND @EndRrowNumber
ORDER BY SortRowNumber

我想摆脱 CTE 任何帮助将不胜感激。

【问题讨论】:

  • 为什么要摆脱 CTE?
  • 我们没有更好的选择吗?特别是我认为我也可以动态传递列名,但不能动态传递方向。
  • 这被标记为重复引用,但我认为使用 sp_executesql 有更好的解决方案

标签: sql sql-server common-table-expression


【解决方案1】:

您可以将 case 表达式移动到 ORDER BY:

SELECT    ED.JobExecutionID
        , ED.RowNumber
        , ED.ErrorMessage
        , ED.RowData    
FROM ExceptionDetails ED        
JOIN ExecutionDetails IED ON IED.JobExecutionID = ED.JobExecutionID
WHERE ED.JobExecutionID = @JobExecutionId
ORDER BY CASE 
         WHEN @SortKey = 'RowNumber' AND @SortDirection = 'Ascending' THEN ROW_NUMBER() OVER (ORDER BY ED.RowNumber ASC)
         WHEN @SortKey = 'RowNumber' AND @SortDirection = 'Descending' THEN ROW_NUMBER() OVER (ORDER BY ED.RowNumber DESC)
         WHEN @SortKey = 'ErrorMessage' AND @SortDirection = 'Ascending' THEN ROW_NUMBER() OVER (ORDER BY ED.ErrorMessage ASC)
         WHEN @SortKey = 'ErrorMessage' AND @SortDirection = 'Descending' THEN ROW_NUMBER() OVER (ORDER BY ED.ErrorMessage DESC)
         WHEN @SortKey = 'RowData' AND @SortDirection = 'Ascending' THEN ROW_NUMBER() OVER (ORDER BY ED.RowData ASC)
         WHEN @SortKey = 'RowData' AND @SortDirection = 'Descending' THEN ROW_NUMBER() OVER (ORDER BY ED.RowData DESC)
         ELSE ROW_NUMBER() OVER (ORDER BY ED.RowNumber ASC)
         END 

【讨论】:

  • 是的,但是 OP 也受到 calc:WHERE SortRowNumber BETWEEN @StartRowNumber AND @EndRrowNumber 的限制。我想您可以在 where 子句中再次添加 case 语句,但是派生表或 CTE 或存储过程会更简洁。
  • @Andrew 是的,我完全忽略了这一点,好眼光。我也同意 CTE 方法。我真的只是回答表明CASE和ROW_NUMBER可以直接在ORDER BY中使用。我猜可以使用OFFSET @StartRowNumber ROWS FETCH NEXT @EndRowNumber-@StartRowNumber ROWS ONLY 这个方法。
  • 是的,我可以使用这样的 order by 子句 - ROW_NUMBER() OVER(ORDER BY @SortKey) AS SortRowNumber 并且它动态地使用 @SortKey 并且工作正常,但不知何故我无法通过 ASC/以同样的方式 DESC。
  • @Gaurav 您必须像上面一样添加完整的内容,其中方向是根据每个案例结果进行硬编码的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-07
  • 2016-06-13
  • 2014-01-13
  • 2018-02-14
  • 1970-01-01
相关资源
最近更新 更多