我编写了一个存储过程,它根据用户选择的列返回排序(升序或降序)的数据。 为了实现这一点,我在 order by 子句 中使用了 Case 语句,如以下代码片段
ORDER BY
CASE WHEN p_filter_type = 'ASC' THEN
CASE p_filter_column
WHEN 'projectCode' THEN projectCode -- varchar field
WHEN 'visaType' THEN visaType -- varchar field
WHEN 'approveRejectStatus' THEN `status` -- varchar field
WHEN 'createdDate' THEN createdDate
WHEN 'employeeID' THEN employeeId -- int field
WHEN 'requestId' THEN requestId -- int field
WHEN 'country' THEN country -- varchar field
WHEN 'serviceDesk' THEN serviceDesk -- varchar field
END
END,
CASE WHEN p_filter_type = 'DESC' THEN
CASE p_filter_column
WHEN 'projectCode' THEN projectCode -- varchar field
WHEN 'visaType' THEN visaType -- varchar field
WHEN 'approveRejectStatus' THEN `status` -- varchar field
WHEN 'createdDate' THEN createdDate
WHEN 'employeeID' THEN employeeId -- int field
WHEN 'requestId' THEN requestId -- int field
WHEN 'country' THEN country -- varchar field
WHEN 'serviceDesk' THEN serviceDesk -- varchar field
END
END DESC
Issue in this code is that it does not sort data properly if any column with integer data type is selected. It considers integer value as varchar and sorts the data accordingly
例如 它返回
10
1
2
3
如果按升序顺序选择requestId。
我尝试使用几种解决方案来解决该问题,例如使用 ABS() 将 varchar 值转换为整数等,但它们并不能帮助我解决问题。
如果你们能帮我解决这个问题,我将不胜感激
最佳答案
事实上,当您组合这样的不同数据类型时,表达式会转换为 varchar
,即使 p_filter_type 和 p_filter_column 指示仅数字列应该确定该表达式的结果。
解决此问题的一种方法是为每种可能性创建一个单独的 order by
表达式,为所有可能性生成 null
(相关的除外) 。这样每个表达式都可以坚持自己的数据类型:
ORDER BY
CASE WHEN p_filter_type = 'ASC' AND p_filter_column = 'projectCode'
THEN projectcode END ASC,
CASE WHEN p_filter_type = 'ASC' AND p_filter_column = 'visaType'
THEN visaType END ASC,
CASE WHEN p_filter_type = 'ASC' AND p_filter_column = 'approveRejectStatus'
THEN status END ASC,
CASE WHEN p_filter_type = 'ASC' AND p_filter_column = 'createdDate'
THEN createdDate END ASC,
CASE WHEN p_filter_type = 'ASC' AND p_filter_column = 'employeeID'
THEN employeeID END ASC,
CASE WHEN p_filter_type = 'ASC' AND p_filter_column = 'requestId'
THEN requestId END ASC,
CASE WHEN p_filter_type = 'ASC' AND p_filter_column = 'country'
THEN country END ASC,
CASE WHEN p_filter_type = 'ASC' AND p_filter_column = 'serviceDesk'
THEN serviceDesk END ASC,
CASE WHEN p_filter_type = 'DESC' AND p_filter_column = 'projectCode'
THEN projectcode END DESC,
CASE WHEN p_filter_type = 'DESC' AND p_filter_column = 'visaType'
THEN visaType END DESC,
CASE WHEN p_filter_type = 'DESC' AND p_filter_column = 'approveRejectStatus'
THEN status END DESC,
CASE WHEN p_filter_type = 'DESC' AND p_filter_column = 'createdDate'
THEN createdDate END DESC,
CASE WHEN p_filter_type = 'DESC' AND p_filter_column = 'employeeID'
THEN employeeID END DESC,
CASE WHEN p_filter_type = 'DESC' AND p_filter_column = 'requestId'
THEN requestId END DESC,
CASE WHEN p_filter_type = 'DESC' AND p_filter_column = 'country'
THEN country END DESC,
CASE WHEN p_filter_type = 'DESC' AND p_filter_column = 'serviceDesk'
THEN serviceDesk END DESC
例如,当 p_filter_type = 'DESC'
和 p_filter_column = 'employeeID'
时,上面的 ORDER BY
子句实际上解析为以下内容:
ORDER BY
NULL ASC,
NULL ASC,
NULL ASC,
NULL ASC,
NULL ASC,
NULL ASC,
NULL ASC,
NULL ASC,
NULL DESC,
NULL DESC,
NULL DESC,
NULL DESC,
employeeID DESC,
NULL DESC,
NULL DESC,
NULL DESC
其排序方式应与您刚刚编写的相同:
ORDER BY
employeeID DESC
混合解决方案
您当然可以采用某种中间解决方案,将具有相同数据类型的字段分组到一个表达式中,这样就不会发生数据类型转换。这样,您的 order by
子句中可能会有 6 个表达式:一个用于 varchar
字段,一个用于 int
字段,一个用于 日期
字段,然后按降序大小写重复每个字段:
ORDER BY
CASE WHEN p_filter_type = 'ASC' THEN
CASE p_filter_column -- all varchar fields
WHEN 'projectCode' THEN projectCode
WHEN 'visaType' THEN visaType
WHEN 'approveRejectStatus' THEN status
WHEN 'country' THEN country
WHEN 'serviceDesk' THEN serviceDesk
END
END ASC,
CASE WHEN p_filter_type = 'ASC' THEN
CASE p_filter_column -- all int fields
WHEN 'employeeID' THEN employeeId
WHEN 'requestId' THEN requestId
END
END ASC,
CASE WHEN p_filter_type = 'ASC' THEN
CASE p_filter_column -- all date fields
WHEN 'createdDate' THEN createdDate
END
END ASC,
CASE WHEN p_filter_type = 'DESC' THEN
CASE p_filter_column -- all varchar fields
WHEN 'projectCode' THEN projectCode
WHEN 'visaType' THEN visaType
WHEN 'approveRejectStatus' THEN status
WHEN 'country' THEN country
WHEN 'serviceDesk' THEN serviceDesk
END
END DESC,
CASE WHEN p_filter_type = 'DESC' THEN
CASE p_filter_column -- all int fields
WHEN 'employeeID' THEN employeeId
WHEN 'requestId' THEN requestId
END
END DESC,
CASE WHEN p_filter_type = 'DESC' THEN
CASE p_filter_column -- all date fields
WHEN 'createdDate' THEN createdDate
END
END DESC
关于MySql排序工作异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42481906/