14

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

M1, M14, M3, M30, M4, M40

当我想要:

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

有任何想法吗?

4

7 回答 7

16

您可以在 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)
于 2012-08-23T18:04:01.093 回答
3

如果字符串的开头可以有多个字符,例如 like '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

这将首先按字符串的字符部分排序,然后是字符串中提取的数字部分,只要字符串开头有 <=7 个字符。如果您需要更多,您可以将附加WHEN的 s 链接到CASE语句中。

于 2012-08-23T18:29:34.960 回答
2

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

V12345 V1000000 V92832

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

使用它解决了我的问题:

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

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

于 2013-07-16T18:21:19.640 回答
1

您可以使用:

order by name,SUBSTRING(name,1,LENGTH(name)-1)
于 2012-08-23T18:07:24.027 回答
0

它将数字和字母分开。

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; 
于 2013-04-08T12:35:14.297 回答
0

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

SELECT * FROM table ORDER BY ABS(SUBSTR(field,1));
于 2016-11-08T13:19:06.227 回答
0

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

SELECT * FROM table_name ORDER BY LENGTH(col_name) DESC, col_name DESC LIMIT 1 
于 2020-07-02T10:23:54.820 回答