MySQL 按案例排序将 Tinyint 转换为字符串

MySQL Order By Case Casting Tinyint to String

我有以下查询:

SELECT
    id,
    display_order
FROM 
    data_element_value
WHERE 
       key_id = 32
ORDER BY 
    CASE WHEN (display_order IS NOT NULL) THEN 
        display_order
    ELSE 
        `value` 
    END

预期输出为:

id                    display_order
1                     1
13                    2
15                    3
16                    10

但是,我得到:

id                    display_order
1                     1
16                    10
13                    2
15                    3

我试过将 display_order 转换为 UNSIGNED

CASE WHEN (display_order IS NOT NULL) THEN
    CAST(display_order as UNSIGNED)
ELSE
    `VALUE`
END

我也试过:

CASE WHEN (display_order IS NOT NULL) THEN
    display_order + 0
ELSE
    `VALUE`
END

但这似乎没有帮助。

列数据类型为 tinyint(2), unsigned, and allow nulls for display_order

编辑

这里是describe data_element_value

Field           Type                Null    Key Default Extra
id              int(11)             NO      PRI (null)  auto_increment
key_id          int(11)             NO      MUL (null)  
value           varchar(50)         NO          (null)  
sub_title       varchar(125)        YES         (null)  
chart_color     char(7)             YES         (null)  
display_order   tinyint(2) unsigned YES         (null)  

我可以做些什么来纠正这个问题吗?

CASE 中所述:

The return type of a CASE expression is the compatible aggregated type of all return values, but also depends on the context in which it is used. If used in a string context, the result is returned as a string. If used in a numeric context, the result is returned as a decimal, real, or integer value.

由于您的 value 列是字符串类型,您将不得不 CAST 单独 value 列,或者整个 CASE 表达式,以实现你想要的结果。在这种情况下,COALESCE() 也比 CASE 更简洁:

SELECT
    id,
    display_order
FROM 
    data_element_value
WHERE 
    key_id = 32
ORDER BY 
    COALESCE(display_order, CAST(`value` AS UNSIGNED))

您可以使用没有 casecoalesce 语句的简单 order by,它会工作得很好。

SELECT
    id,
    display_order
FROM 
    data_element_value
WHERE 
       key_id = 32
ORDER BY `display_order`, `value`