我需要根据对参数的Integer输入来按列排序结果集。
问题是,我需要为OrderBy使用CASE,似乎代码接受case列中的第一个'TYPE'......任何其他类型都失败。
我的代码是这样的:
WITH error_table AS
(
SELECT Row_Number() OVER
(ORDER BY
CASE @orderBy
WHEN 1 THEN received_date -- Last Rx'd message
WHEN 2 THEN message_id -- Message Id
WHEN 3 THEN zibmat.short_name -- Message action type
WHEN 4 THEN error_action.short_name -- Status type
WHEN 5 THEN ime.[allocated_date] -- Allocated Date
ELSE received_date
END) AS RowNumber
,ime.[ijis_message_error_id]
,ime.[message_id]
,ime.[message_version]
因此,当OrderBy为1时,它可以工作。它按rx_date进行排序...但是当我发送它2时,它会因数据时间转换错误而失败。
看起来所有类型都必须相同......
发送5个工作正常,因为这也是日期时间。
我有办法解决这个问题吗?
答案 0 :(得分:10)
CASE语句必须只解析为一种数据类型。这与您知道@orderby只选择一个分支并且它将是特定数据类型无关。
你可以使用类似这样的东西,它会很笨重但会起作用。
ORDER BY
CASE @orderBy WHEN 1 THEN received_date -- Last Rx'd message
WHEN 2 THEN 0
WHEN 3 THEN 0
WHEN 4 THEN 0
WHEN 5 THEN ime.[allocated_date] -- Allocated Date
ELSE received_date END,
CASE @orderBy WHEN 1 THEN 0
WHEN 2 THEN message_id -- Message Id
WHEN 3 THEN 0
WHEN 4 THEN 0
WHEN 5 THEN 0
ELSE 0 END,
CASE @orderBy WHEN 1 THEN ''
WHEN 2 THEN ''
WHEN 3 THEN zibmat.short_name -- Message action type
WHEN 4 THEN error_action.short_name -- Status type
WHEN 5 THEN ''
ELSE '' END
答案 1 :(得分:5)
这似乎也有效。
ORDER BY
CASE @orderBy
WHEN 1 THEN CAST(received_date AS SQL_VARIANT) -- Last Rx'd message
WHEN 2 THEN message_id -- Message Id
WHEN 3 THEN zibmat.short_name -- Message action type
WHEN 4 THEN error_action.short_name -- Status type
WHEN 5 THEN ime.[allocated_date] -- Allocated Date
ELSE received_date
END
测试用例(int
,string
,date
)
DECLARE @P INT = Datepart(SECOND, Getdate())%3;
SELECT 'Sorting By ' + CASE @P
WHEN 1 THEN 'modify_date'
WHEN 2 THEN 'object_id'
ELSE 'name'
END
SELECT object_id,
name,
modify_date
FROM sys.objects
ORDER BY CASE @P
WHEN 1 THEN CAST(modify_date AS SQL_VARIANT)
WHEN 2 THEN object_id
ELSE name
END
答案 2 :(得分:1)
我认为下面的选项会更清晰(类似于RichardTheKiwi的方法)
WITH error_table AS
(
SELECT ROW_NUMBER() OVER
(
ORDER BY
CASE WHEN @orderBy = 1 THEN received_date END,
CASE WHEN @orderBy = 2 THEN message_id END ,
CASE WHEN @orderBy = 3 THEN zibmat.short_name END,
CASE WHEN @orderBy =4 THEN error_action.short_name END,
CASE WHEN @orderBy =5 THEN ime.[allocated_date] END
) AS RowNumber
,ime.[ijis_message_error_id]
,ime.[message_id]
--..other columns...
-- FROM YOURTABLE
)