MySql排序工作异常

标签 mysql sql

我编写了一个存储过程,它根据用户选择的列返回排序(升序或降序)的数据。 为了实现这一点,我在 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_typep_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/

相关文章:

php - PHP 中的日期分组

mysql - SQL 年份分组中的 4 周周期

php - 减少 MySQL 查询数量并按正确顺序输出数据

sql - 按左连接表排序

sql - HTML Local Storage 参数替换转义

mysql - 您可以在提供 TOTAL 的 CASE 语句中添加另一行吗?

java - 升级到 5.1.39 之后找不到 mysql-connector-java 驱动程序

Mysql - Concat - 过程执行失败

mysql - 需要帮助构建 SQL SELECT 语句以获取 "top 10 x"

sql - Quick SELECT 有时会超时