繁体   English   中英

MySQL自然排序字母数字值

[英]MySQL natural sorting of alphanumeric values

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

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

可能是提取第一个单词并将第二个单词视为order in子句中的数字:

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)

试试这个查询:

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

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

以下解决方案在以下有关您要自然排序的文本的数字部分的假设下运行良好:

  1. 它必须在列的末尾
  2. 它必须至少有一个空格
  3. 它必须只包含数字 (没有符号,句号或逗号)

我已经设置了以下数据:

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也无法正常使用多字节。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM