在 Mysql 中对“1.1.1”格式类型进行排序
Posted
技术标签:
【中文标题】在 Mysql 中对“1.1.1”格式类型进行排序【英文标题】:Sorting a "1.1.1" format type in Mysql 【发布时间】:2017-01-25 07:58:47 【问题描述】:我想对这种类型进行排序 1.1、1.1.1、1.1.2、2.1、2.1.1、2.3、..等。像这样,我为此列使用 Varchar 数据类型但是发生的情况是它在 10.1.1 之后排序正确直到 9.9.9,这里的排序发生如下 1.1、1.1.1、1.1.2、10.1.1、强> 2.1、2.1.1、...等。像这样我也尝试使用 DECIMAL 但没有结果。
【问题讨论】:
在数据库中插入时,再创建一列,如 unique_id,该列将是唯一的,可用于在检索时进行排序。 作为 hack,您可以使用 INET_ATON 和 INET_NTOA 请参阅***.com/questions/7508313/… 并注意所有使用函数对结果进行排序的解决方案都不能使用索引,因此它可能会很慢。如果性能很关键,请考虑将字符串的每个部分存储为单独的列,以便对其进行索引。 【参考方案1】:您可以将值解析为三个不同的列,这在您的数据库中不是必需的,应用程序代码会更容易做到这一点。然后就变成了
select ... order by col1, col2, col3
【讨论】:
【参考方案2】:一个好主意是将您的号码存储为固定大小,例如
1.1.1 => 001001001(或简称 1001001) 1.1 => 1001000 9.9.9 => 9009009这样您可以将变量存储为数字。检索后,您将不得不使用模数将您的数字设置回字符串。主要限制是您必须决定每个段有多少可用(在我的示例中,999 是每个段的最大值。 此方法是我存储要排序的 IP 地址的方式(例如 192.168.1.1 变为 192168001001)。
【讨论】:
【参考方案3】:试试这个:
SELECT
*
FROM
my_table
ORDER BY
CAST(SUBSTRING_INDEX(my_col, '.', 1) AS UNSIGNED) ASC,
CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(my_col, '.', -2), '.', 1) AS UNSIGNED) ASC,
CAST(SUBSTRING_INDEX(my_col, '.', -1) AS UNSIGNED) ASC
基本上它获取字符串每个部分的子字符串,并使用字符串的每个部分对行进行排序,从左到右。
更新:上述查询正好适用于 3 个数字。但是如果你想支持 4 个数字,那么使用这个查询:
SELECT
*
FROM
my_table
ORDER BY
SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(my_col, '.'), '.', 1), '.', -1) + 0
, SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(my_col, '.'), '.', 2), '.', -1) + 0
, SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(my_col, '.'), '.', 3), '.', -1) + 0
, SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(my_col, '.'), '.', 4), '.', -1) + 0
如果您想支持更多数字,只需添加以下内容,将“XX”替换为下一个数字:
, SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(my_col, '.'), '.', XX), '.', -1) + 0
感谢这个非常相似的问题的答案:https://***.com/a/17849200/2518200
【讨论】:
您好感谢您的回复,我尝试了这个但仍然排序没有得到正确的结果。结果从上面查询:7.3.1.1, 7.3.1.2, 7.3.1.4, 7.3.2.2, 7.2.4, 12.2.1, 12.2 结果 Desire 7.2.4, 7.3.1.1, 7.3.1.2, 7.3.1.4, 7.3 .2.2、12.2、12.2.1 @Jaineshshah 抱歉,该查询是针对 3 个数字的。由于您最多有 4 个或更多数字,因此我不得不更改答案。请参阅我更新的答案。您可以将这个新查询用于任何长度。以上是关于在 Mysql 中对“1.1.1”格式类型进行排序的主要内容,如果未能解决你的问题,请参考以下文章