在ORDER BY子句中使用CASE语句,使用不同的数据类型

时间:2015-03-18 11:24:32

标签: sql-server tsql sql-server-2008-r2

我想在CASE子句中使用ORDER BY语句,如下所示:

DECLARE @SortOr TINYINT
SELECT  @SortOr = 1

SELECT  *
FROM    [Table]
ORDER BY CASE WHEN @SortOr = 1 THEN col1
              ELSE col2
         END

但它引发了一个错误:

  

无法将varchar转换为tinyint。

背后的逻辑是什么?怎么解决它?

2 个答案:

答案 0 :(得分:4)

@Damien_The_Unbeliever在评论中完美陈述的根本问题是:

  

单个CASE表达式必须生成一种数据类型的值。因此,如果您有THEN个生成不同数据类型的值,系统会使用precedence rules来决定要转换哪些数据类型。

您可以复制CASE语句来解决此问题,其中每个CASE都返回单个值/数据类型。这比将另一个答案中建议的所有值转换为VARCHAR要好,这也应该表现得更好(您必须进行测试):

所以新的ORDER BY子句将如下所示:

ORDER BY CASE WHEN @SortOr = 1 THEN col1 
         END ,
         CASE WHEN @SortOr != 1 THEN col2
         END -- If you need DESC it goes after END

答案 1 :(得分:0)

CASE语句的所有返回值转换为VARCHAR,它会起作用。

SQL Server会尝试隐式转换所有返回的值,因为它们是相同表达式的一部分,而SQL Server希望它们实际上是同一类型;它会尝试转换为INT,因为INT的{​​{3}}高于VARCHAR;所以你应该明确地为它设置相同的类型。