【问题标题】:How to ORDER BY varchar field as number?如何将 varchar 字段作为数字排序?
【发布时间】:2012-07-28 13:04:51
【问题描述】:

我在排序/排序方面遇到问题,无法按我需要的方式工作。

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

怎么做?

【问题讨论】:

  • 听起来您使用的是varchar 而不是decimal
  • 列中是否有实际文字80.0 proc
  • yes varchar, yes column contains text: 80.0 proc, etc.
  • 为什么它们都包含文字proc?连列都命名为procI dont get it
  • Natural Sort in MySQL 的可能重复项 - 如果这不起作用,请查看与其相关的所有问题。

标签: mysql sql


【解决方案1】:

看起来“proc”是一个字符串(varchar 字段),所以它是按词法排序的。如果是这样,您可能可以通过以下方式订购它

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

请注意,这样的查询会非常慢,对于任何严重的使用,最好使用数字列来存储数字数据。

【讨论】:

  • 我没想到它会起作用,但it does
  • 有趣,会认为将 '80.0 proc' 转换为十进制会失败。有人知道为什么吗?
  • @Bort:找不到此in the docs 的任何规范,所以我只是猜测他们选择更宽松一点而不是返回 NULL,这可能是失败的唯一方法这些功能。
  • @Bort:在我的测试中,就好像该函数读取字符串直到第一个“无效”字符,直到字符串不能再转换为十进制。它对可以转换的部分进行转换。公平的警告,它认为“逗号”是无效字符,CONVERT('123,456.78',DECIMAL) 将返回 123
  • 有一个类似的问题,最初排序的字段是 alpha,例如数学、科学、动物学。然后决定类别不适用于某些项目,因此将事物分组为级别,例如1 级,2 级。然后他们决定对于一个应用程序,他们只需对所有内容进行编号。因此,在数据库行的一半中,该字段是一个 varchar,而在一半中它实际上是一个整数。我使用的转换是 ORDER BY CONVERT(group, UNSIGNED) WHERE app = 'App1'
【解决方案2】:

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

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

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

【讨论】:

  • 不错,但我无法更改,需要解决方案。
  • 双精度或浮点数不能包含像“100.0 proc”这样的字母数字值。
  • 是的,如果可能的话,应该适当地更改列(并且'proc' 出现在每一行中的事实是一个问题)。但是,根据实际存储的内容,浮点类型不是正确的选择——我可能建议使用整数类型(如果小数位无关紧要)或小数类型(如果需要精确的准确性)。跨度>
  • @Ray 请先在您的服务器中检查您的答案,然后再发布
  • 它显然有效,只有needs to be writtencast(proc as decimal)
【解决方案3】:

您的桌子设计存在根本问题。不要在VARCHAR 列中使用'80.0 proc' 之类的值,而应将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 无论如何都会相当笨拙(解决问题来源:您的列数据类型)。

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

【讨论】:

    【解决方案4】:

    如果你的小数位数总是相同,我的做法是:

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

    【讨论】:

      猜你喜欢
      • 2012-01-20
      • 2011-06-08
      • 2014-06-10
      • 2017-10-06
      • 1970-01-01
      • 2011-01-04
      • 1970-01-01
      • 1970-01-01
      • 2017-06-10
      相关资源
      最近更新 更多