简体   繁体   English

如何使用CASE在select语句的列位置对存储过程中的数据进行排序

[英]How to sort data in stored procedure with column positions of select statement with CASE

This is not working 这不行

ORDER BY 
    CASE 
       WHEN @OrderBy = 'EndDateInDays' AND @OrderByDirection = 'D' 
          THEN 10 
    END DESC,
    CASE 
       WHEN @OrderBy = 'EndDateInDays' AND @OrderByDirection != 'D' 
          THEN 10 
    END

Where this one is working 这个人在哪里工作

ORDER BY 10 DESC

As per documentation, 根据文档,

ORDER BY order_by_expression

order_by_expression Specifies a column or expression on which to sort the query result set. order_by_expression指定要对查询结果集进行排序的列或表达式 A sort column can be specified as a name or column alias, or a nonnegative integer representing the position of the column in the select list. 可以将排序列指定为名称或列别名,或者指定列在选择列表中的位置的非负整数。

Source: SELECT - ORDER BY Clause (Transact-SQL) 来源: SELECT-ORDER BY子句(Transact-SQL)

You are specifying an expression, hence the SQL Server does not sort by value in column #10. 您正在指定一个表达式,因此SQL Server不会按列#10中的值排序。 Instead it sorts your rows by a constant value '10', which results in no sort being performed. 相反,它将按常量值“ 10”对行进行排序,这将导致不执行任何排序。

Suggested solution 建议的解决方案

Move all complex columns into a CROSS APPLY sub-query and add another CROSS APPLY with a sorting column: 将所有复杂的列移动到CROSS APPLY子查询中,并使用排序列添加另一个CROSS APPLY:

SELECT  F.Id
        ,cols.Favourite
        ,F.Agent
        ,F.Name
        ,cols.DatePublished
        ,UF.ToolTip
        ,F.CreationDate
FROM MyTable F
  INNER JOIN MyTable2 UF
    ON f.Id = UF.Id
CROSS APPLY (
  SELECT       (CASE WHEN UFF.[Id] IS NULL THEN CONVERT(BIT, 0) ELSE CONVERT(BIT, 1) END) AS Favourite
              ,CONVERT(Datetime, F.[Date] , 103) AS DatePublished
) cols
CROSS APPLY (
SELECT         -- Make sure to correctly cast all numeric and date values to text
               CASE WHEN    @OrderBy = 'EndDateInDays' THEN CONVERT(VARCHAR(100), F.[EndDateDate], 126)
                    WHEN    @OrderBy = 'Name' THEN F.Name
                    WHEN    @OrderBy = 'DatePublished' THEN cols.DatePublished
                    ELSE CONVERT(VARCHAR(100), F.Id) -- This is default sort
                  END AS [SortCol]

) sort
ORDER BY 
         CASE WHEN @OrderByDirection = 'D' THEN sort.[SortCol] END DESC
        ,CASE WHEN @OrderByDirection != 'D' THEN sort.[SortCol] END
;

You can use the column alias. 您可以使用列别名。 Let's say it is EndDateInDays : 假设它是EndDateInDays

ORDER BY (CASE WHEN @OrderBy = 'EndDateInDays' AND @OrderByDirection = 'D' 
               THEN EndDateInDays
          END) DESC,
         (CASE WHEN @OrderBy = 'EndDateInDays' AND @OrderByDirection <> 'D' 
               THEN EndDateInDays 
          END)

If EndDateInDays is a number (as suggested by the name), you could do: 如果EndDateInDays是一个数字(如名称所示),则可以执行以下操作:

ORDER BY (CASE WHEN @OrderBy = 'EndDateInDays' AND @OrderByDirection = 'D' 
               THEN - EndDateInDays
               WHEN @OrderBy = 'EndDateInDays' AND @OrderByDirection <> 'D' 
               THEN EndDateInDays 
          END)

Also, be careful if you start combining multiple columns. 另外,如果您开始合并多列,请小心。 It is better to have a separate CASE expression for each column to prevent inadvertent type mismatching. 最好为每个列使用单独的CASE表达式,以防止意外的类型不匹配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM