如何将varchar字段作为数字排序?

时间:2012-07-30 19:58:14

标签: mysql sql

我的排序/订单有问题,而不是像我需要的那样工作。

SELECT `proc` FROM `table` ORDER BY `proc` DESC;

结果:

80.0 proc
70.0 proc
60.0 proc
50.0 proc
40.0 proc
200.0 proc
20.0 proc
190.0 proc
180.0 proc
170.0 proc
160.0 proc
150.0 proc
140.0 proc
130.0 proc
120.0 proc
110.0 proc
100.0 proc

我需要的是:

200.0 proc
190.0 proc
180.0 proc
170.0 proc
160.0 proc
150.0 proc
140.0 proc
130.0 proc
120.0 proc
110.0 proc
100.0 proc
90.0 proc
80.0 proc
70.0 proc
60.0 proc
50.0 proc
40.0 proc
20.0 proc

怎么做?

4 个答案:

答案 0 :(得分:44)

看起来“proc”是一个字符串(varchar字段),因此它会在词汇上进行排序。如果是这样,您可以通过

订购
SELECT `proc` FROM `table` ORDER BY convert(`proc`, decimal) DESC;

请注意,此类查询速度非常慢,对于任何严重的使用情况,最好使用数字列存储数字数据。

答案 1 :(得分:7)

proc的列字段是VARCHAR或CHAR,它将其视为文字字符串 - 按字母顺序排序。

将列转换为double或float或转换值

SELECT `proc` FROM `table` ORDER BY CAST(`proc` AS decimal) DESC;

答案 2 :(得分:1)

您的桌面设计存在根本性的问题。您应该将'80.0 proc'保留在VARCHAR类型的列(或适合您的数据的任何合适的数字类型)中,而不是在80.0列中使用REAL之类的值。您可以进行动态转换,仅用于ORDER BY表达式,但这也可能会降低查询性能。

在这里添加“ proc ”似乎不太有用,它也会阻止你进行简单的转换。

令人惊讶的是(见 che 的答案),显然,convert(..., decimal)能够忽略尾随的垃圾。不过,这不是你应该依赖的东西。

documentation on this aspect of the conversion并不是特别清楚。值得一读的是该部分要注意字符串/数字的限制(通常会发生这种情况),例如:

mysql> SELECT '18015376320243459' = 18015376320243459;
        -> 0

如果这种行为发生了变化,你可以在这种情况下使用replace(),只是为了摆脱' proc'

对于更复杂的东西,你可以使用正则表达式替换来从字符串中提取数值并在排序之前将其强制转换为数字,但是this is not supported out of the box in MySQL并且无论如何都会相当笨重(修复问题)在其来源:您的列数据类型)。

要处理遗留数据,您可以添加一个额外的列并使用外部程序(使用任何能够进行正则表达式替换的语言),这应该不会太困难。

答案 3 :(得分:0)

如果您始终具有相同的小数点位数,那么我的方法是:

SELECT `proc` FROM `table` ORDER BY LENGTH(proc) DESC, proc DESC;