MySQL自然排序字母数字值

时间:2014-05-31 06:35:33

标签: php mysql sorting

我想对以下数据排序字母+字母数字值:

In-Direct Labor
Level 1
Level 10
Level 11
Level 12
Level 13
Level 14
Level 15
Level 16
Level 17
Level 2
Level 3
Level 4
Level 5
Level 6
Level 7
Level 8
Level 9
Risers  Risers
Roof/Penthouse
Site

我尝试了以下解决方案,但它没有以我想要的方式返回结果

http://www.copterlabs.com/blog/natural-sorting-in-mysql/

In-Direct Labor
Level 1
Level 2
Level 3
Level 4
Level 5
Level 6
Level 7
Level 8
Level 9
Level 10
Level 11
Level 12
Level 13
Level 14
Level 15
Level 16
Level 17
Risers  Risers
Roof/Penthouse
Site

3 个答案:

答案 0 :(得分:3)

可以提取第一个单词,并在顺序子句中将第二个单词视为数字:

select *
from ab
order by 
   substring(col,1, case when locate(' ',col) = 0 then 100 else locate(' ',col) end ),
   substring(col,case when locate(' ',col) = 0 then 100 else locate(' ',col) end ) + 0;

-- col contains your field.

+-----------------+
| col             |
+-----------------+
| In-Direct Labor |
| Level 1         |
| Level 2         |
| Level 3         |
| Level 4         |
| Level 5         |
| Level 6         |
| Level 7         |
| Level 8         |
| Level 9         |
| Level 10        |
| Level 11        |
| Level 12        |
| Level 13        |
| Level 14        |
| Level 15        |
| Level 16        |
| Level 17        |
| Risers  Risers  |
| Roof/Penthouse  |
| Site            |
+-----------------+
21 rows in set (0.01 sec)

答案 1 :(得分:0)

尝试此查询:

SELECT * from Your_Table
ORDER BY substring(in_direct_column,6) + 0

答案 2 :(得分:0)

好的......在用SQLFiddle稍微愚弄之后,我会对此进行一次拍摄。

以下解决方案适用于以下有关您要自然排序的文本的数字部分的假设:

  1. 必须位于列的末尾
  2. 必须至少有一个空格
  3. 必须仅包含数字(无符号,句号或逗号)
  4. 我已设置以下数据:

    CREATE TABLE phrases(phrase TEXT);
    INSERT INTO phrases VALUES 
    ('In-Direct Labor'),
    ('Level 1'),
    ('Level 2'),
    ('Level 3'),
    ('Level 4'),
    ('Level 5'),
    ('Level 6'),
    ('Level 7'),
    ('Level 8'),
    ('Level 9'),
    ('Level 10'),
    ('Level 11'),
    ('Level 12'),
    ('Level 13'),
    ('Level 14'),
    ('Level 15'),
    ('Level 16'),
    ('Level 17'),
    ('Risers  Risers'),
    ('Roof/Penthouse'),
    ('Site'),
    ('Square 1'),
    ('Square 4'),
    ('Square 9'),
    ('Square 16'),
    ('Square 25'),
    ('Square 36'),
    ('Square 49'),
    ('Square 64'),
    ('Square 81'),
    ('Square 100'),
    ('Square 121');
    

    以下是查询:

    SELECT phrase,
      (CASE
        WHEN phrase REGEXP '[0-9]+$' THEN LEFT(phrase,
          LENGTH(phrase)-LENGTH(SUBSTRING_INDEX(phrase,' ',-1)))
        ELSE                              phrase
      END)                             AS phrase_base,
      SUBSTRING_INDEX(phrase,' ',-1)+0 AS phrase_index
    FROM phrases
    ORDER BY phrase_base, phrase_index;
    

    这会根据需要(以及插入时)返回行。

    如何运作

    REGEXP隔离以数字字符串结尾的行,并将其前面的所有行拉出并放入phrase_base中。对于其他行,全文内容将直接复制到phrase_base。

    末尾的数字字符串转换为数字(phrase_index)。

    对phrase_base和phrase_index的组合进行排序。

    要注意的事项

    在大数据上,这将是缓慢的,因为索引不会有太多帮助

    这可能不适用于多字节文本列,因为LENGTH函数计算字节数而不是字符数。我认为REGEXP也无法正常使用多字节。