mysql:orderby使用长字符串生成错误的顺序

zzzyeukh  于 2021-06-23  发布在  Mysql
关注(0)|答案(3)|浏览(359)

我有一张table VARCHAR(255) 包含以下字符串的列。

1
2
5
22
text

我需要规范化字符串并像那样对它们排序。我给他们加上前缀 0 ,以便在订购时获得以下信息:

0001
0002
0005
0022
text

以下是查询:

SELECT right(concat('000000000000000000000000000000000000', test), 36)
FROM my_table
ORDER BY right(concat('000000000000000000000000000000000000', test), 36);

如果 number_of_charsright() 调用足够小(比如说16)顺序是正确的,但是如果我使用36,顺序是不正确的:string 5 在前面 2 .

000000000000000000000000000000000005
000000000000000000000000000000000002

问:这种行为的原因是什么?是虫子吗?如何修复?
我的table是这样的:

mysql> describe my_table;
+----------------------------+--------------+------+-----+---------+-------+
| Field                      | Type         | Null | Key | Default | Extra |
+----------------------------+--------------+------+-----+---------+-------+
| id                         | varchar(255) | NO   | PRI | NULL    |       |
| test                       | varchar(255) | NO   | UNI | NULL    |       |
+----------------------------+--------------+------+-----+---------+-------+

我正在使用MySQL5.7.15

kzmpq1sx

kzmpq1sx1#

这是高度可重复性和相当好奇。例如,这会产生错误的排序:

SELECT right(concat(repeat('0', 36), test), 36) as val
FROM (select 'abcd' as test union all
      select '5' as test union all
      select '2' as test union all
      select '13' as test union all
      select '10013' as test union all
      select 'def' as test
     ) t
ORDER BY val ;

有趣的是 DESC 似乎解决了问题,但是 ASC 不。
通常,在这种情况下,您希望首先是数字,然后是所有文本。您的版本将把非数字与相同长度的数字穿插在一起。
我建议使用单独的表达式:

ORDER BY (left(test, 1) between '0' and '9') desc,
         test + 0,
         test

这种排序似乎确实有效。

eufgjt7s

eufgjt7s2#

您使用的是按顺序排列的字符串,因此它不会以不同的方式考虑数字和字符串。例如你有11,12,01,03,你会得到
01 11 12 03只有这样

csbfibhn

csbfibhn3#

似乎在21个字符之后,右边的子字符串加上字符串填充就不起作用了。。但是您可以使用简单的lpad来完成这项工作,也可以用于100或更多

SELECT test
FROM my_table
ORDER BY lpad(test,100, '0')

相关问题