【问题标题】:MySQL order by string with numbersMySQL按带数字的字符串排序
【发布时间】:2012-08-19 07:23:05
【问题描述】:

我有诸如M1 M3 M4 M14 M30 M40 之类的字符串(实际上是字母后的任何 int 2-3 位数字) 当我执行“ ORDER BY name ”时,它会返回:

M1, M14, M3, M30, M4, M40

当我想要时:

M1, M3, M4, M14, M30, M40 它将整个事物视为字符串,但我想将其视为字符串 + int

有什么想法吗?

【问题讨论】:

标签: mysql sql-order-by collation


【解决方案1】:

我在项目中使用的另一种方法是:

SELECT * FROM table_name ORDER BY LENGTH(col_name) DESC, col_name DESC LIMIT 1 

【讨论】:

    【解决方案2】:

    你可以使用:

    order by name,SUBSTRING(name,1,LENGTH(name)-1)
    

    【讨论】:

      【解决方案3】:

      尝试使用 SUBSTR 删除字符。然后使用 ABS 从字段中获取绝对值:

      SELECT * FROM table ORDER BY ABS(SUBSTR(field,1));
      

      【讨论】:

        【解决方案4】:

        我无法解决我对 MLS 号码进行排序的问题,如下所示:

        V12345 V1000000 V92832

        问题是 V1000000 的价值并未高于其他产品,即使它更大。

        使用它解决了我的问题:

        ORDER BY CAST(SUBSTR(col_name FROM 2) AS UNSIGNED) DESC
        

        刚刚删除了SUBSTR(col_name FROM 1 FOR 1)

        【讨论】:

          【解决方案5】:

          它将数字和字母分开。

          SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(
          SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(col,'1', 1), '2', 1), '3', 1), '4', 1), '5', 1), '6', 1)
          , '7', 1), '8', 1), '9', 1), '0', 1) as new_col  
          FROM table group by new_col; 
          

          【讨论】:

            【解决方案6】:

            您可以在 ORDER BY: 中使用 SUBSTR 和 CAST AS UNSIGNED/SIGNED:

            SELECT * FROM table_name ORDER BY
                SUBSTR(col_name FROM 1 FOR 1),
                CAST(SUBSTR(col_name FROM 2) AS UNSIGNED)
            

            【讨论】:

            • 非常感谢!刚刚从 1 FOR 2 更改为 FROM 1 FOR 1 并且可以使用
            • @rocky 如果没有修复格式怎么办,可能的字符串喜欢:test1,1test,te2st,test11,2131,10t,t22g
            【解决方案7】:

            如果字符串的开头可以有多个字符,例如'M10', 'MTR10', 'ABCD50', 'JL8', etc...,则基本上必须从数字的第一个位置获取名称的子字符串。

            不幸的是 MySQL 不支持那种 REGEXP 操作(只返回一个布尔值,而不是实际的匹配)。

            您可以使用此解决方案来模拟它:

            SELECT   name
            FROM     tbl
            ORDER BY CASE WHEN ASCII(SUBSTRING(name,1)) BETWEEN 48 AND 57 THEN
                               CAST(name AS UNSIGNED)
                          WHEN ASCII(SUBSTRING(name,2)) BETWEEN 48 AND 57 THEN
                               SUBSTRING(name,1,1)
                          WHEN ASCII(SUBSTRING(name,3)) BETWEEN 48 AND 57 THEN
                               SUBSTRING(name,1,2)
                          WHEN ASCII(SUBSTRING(name,4)) BETWEEN 48 AND 57 THEN
                               SUBSTRING(name,1,3)
                          WHEN ASCII(SUBSTRING(name,5)) BETWEEN 48 AND 57 THEN
                               SUBSTRING(name,1,4)
                          WHEN ASCII(SUBSTRING(name,6)) BETWEEN 48 AND 57 THEN
                               SUBSTRING(name,1,5)
                          WHEN ASCII(SUBSTRING(name,7)) BETWEEN 48 AND 57 THEN
                               SUBSTRING(name,1,6)
                          WHEN ASCII(SUBSTRING(name,8)) BETWEEN 48 AND 57 THEN
                               SUBSTRING(name,1,7)
                     END,
                     CASE WHEN ASCII(SUBSTRING(name,1)) BETWEEN 48 AND 57 THEN
                               CAST(SUBSTRING(name,1) AS UNSIGNED)
                          WHEN ASCII(SUBSTRING(name,2)) BETWEEN 48 AND 57 THEN
                               CAST(SUBSTRING(name,2) AS UNSIGNED)
                          WHEN ASCII(SUBSTRING(name,3)) BETWEEN 48 AND 57 THEN
                               CAST(SUBSTRING(name,3) AS UNSIGNED)
                          WHEN ASCII(SUBSTRING(name,4)) BETWEEN 48 AND 57 THEN
                               CAST(SUBSTRING(name,4) AS UNSIGNED)
                          WHEN ASCII(SUBSTRING(name,5)) BETWEEN 48 AND 57 THEN
                               CAST(SUBSTRING(name,5) AS UNSIGNED)
                          WHEN ASCII(SUBSTRING(name,6)) BETWEEN 48 AND 57 THEN
                               CAST(SUBSTRING(name,6) AS UNSIGNED)
                          WHEN ASCII(SUBSTRING(name,7)) BETWEEN 48 AND 57 THEN
                               CAST(SUBSTRING(name,7) AS UNSIGNED)
                          WHEN ASCII(SUBSTRING(name,8)) BETWEEN 48 AND 57 THEN
                               CAST(SUBSTRING(name,8) AS UNSIGNED)
                     END
            

            这将首先按字符串的字符部分排序,然后是字符串中提取的数字部分,只要字符串开头有 WHENs 链接到 CASE 语句。

            【讨论】:

            • 它工作了,但是如果它的数字值如下:'M10','40','MTR10','ABCD50','8','JL8','55'跨度>
            • 如果混合字符串和数字之间有干净的数字,则需要在第一个 CASE 工作之前添加 ORDER BY name*1, CASE..。
            猜你喜欢
            • 2018-01-21
            • 2013-07-11
            • 2018-04-20
            • 2011-07-13
            • 1970-01-01
            • 2014-02-01
            • 1970-01-01
            • 2013-12-12
            • 1970-01-01
            相关资源
            最近更新 更多