我想在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。
背后的逻辑是什么?怎么解决它?
答案 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
;所以你应该明确地为它设置相同的类型。