You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL中如何对VARCHAR类型存储的十进制数排序

解决方案

要实现你需要的自然排序,核心是将无小数点的记录的小数部分视为0,而不是误将整个字符串当作小数部分。以下是正确的SQL语句:

SELECT number_of_points
FROM meetings_points
WHERE meeting = 1026
ORDER BY
    -- 第一优先级:按小数点前的整数排序
    CAST(SUBSTRING_INDEX(number_of_points, '.', 1) AS UNSIGNED),
    -- 第二优先级:按小数点后的整数排序,无小数则取0
    CAST(
        CASE 
            WHEN INSTR(number_of_points, '.') > 0 THEN SUBSTRING_INDEX(number_of_points, '.', -1)
            ELSE '0'
        END AS UNSIGNED
    );

或者用更简洁的IF函数写法:

SELECT number_of_points
FROM meetings_points
WHERE meeting = 1026
ORDER BY
    CAST(SUBSTRING_INDEX(number_of_points, '.', 1) AS UNSIGNED),
    CAST(IF(INSTR(number_of_points, '.'), SUBSTRING_INDEX(number_of_points, '.', -1), '0') AS UNSIGNED);

为什么你之前的方法失效?

你之前的所有尝试都忽略了一个关键问题:对于没有小数点的记录(比如15),SUBSTRING_INDEX(number_of_points, '.', -1)会返回整个字符串15,转成整数后是15,比15.1的小数部分1大。这就导致15被排在所有15.x的后面,和预期相反。

而上面的解决方案通过CASE/IF判断是否存在小数点,无小数时强制将小数部分设为0,确保15(小数部分0)排在15.1(小数部分1)、15.11(小数部分11)等所有带小数的记录前面。

验证结果

执行上述SQL后,会得到你想要的排序结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
15.1
15.2
15.3
15.4
15.5
15.6
15.7
15.8
15.9
15.10
15.11
16
17
18

内容的提问来源于stack exchange,提问作者Václav Kraus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 13:08:15