我需要正确排序包含一组分隔数字的字符串列,例如:
1
1.1
1.1.1
1.2
1.2.1
1.10
2
2.1
这些数字用于定义一棵树:例如1
和 2
是顶级节点,1.1
, 1.2
, 和 1.10
是 1
的直系子女.树可以任意深,因此每个条目中的句点数本身没有上限(尽管实际上列的字符限制将强制执行此操作)。
我遇到的问题是标准 ORDER BY
SQL 中的操作将列出 1.10
领先1.2
.这当然是预料之中的,但不幸的是这不是我想要的,因为 10 > 2
.有没有一种有效的方式来获得我的订单?我正在使用 MySQL。
请注意,我不一定对树使用这种编码,所以如果有更容易订购的不同编码,请随时提出建议。然而,这种结构为我提供的一件好事是一种简单的方法来一次恢复所有上游父节点或所有下游子节点,这不适用于更典型的 row/parent_row 模型(到目前为止我所知)。例如,给定 id 1.2.1.4.5
我知道四祖是1
, 1.2
, 1.2.1
, 和 1.2.1.4
, 所有 child (包括直系后代和 child 的 child )都将有一个以 1.2.1.4.5.
开头的 ID .
最佳答案
@Abiel,根据您的评论,每个节点可能没有超过 50 个直接子节点,在这种情况下(62 个子节点就足够了)——正如@Bohemian 在评论中所述——我们可以使用计算机- 可读代码 0-9A-Za-z
( Base 62 Encoding ),我们可以设置一个新的 VARCHAR( 255 ) BINARY
列来帮助我们进行排序。
CREATE TABLE `test`.`tree` (
`computer_readable` VARCHAR( 255 ) BINARY NOT NULL ,
`human_readable` VARCHAR( 255 ) NOT NULL ,
`title` VARCHAR( 255 ) NOT NULL ,
PRIMARY KEY ( `computer_readable` ) ,
INDEX ( `human_readable` )
);
您可能已经注意到,computer_readable
列定义为 BINARY
,因此我们最多可以有 62 个 [0-9A-Za-z]
(而不是 36 个 [0-9a-z]
)每个节点的子节点。
mysql> SELECT 'a' = 'A';
+-----------+
| 'a' = 'A' |
+-----------+
| 1 |
+-----------+
1 row in set (0.00 sec)
mysql> SELECT BINARY 'a' = 'A';
+------------------+
| BINARY 'a' = 'A' |
+------------------+
| 0 |
+------------------+
1 row in set (0.00 sec)
mysql> SELECT BINARY 'a' > 'A';
+------------------+
| BINARY 'a' > 'A' |
+------------------+
| 1 |
+------------------+
1 row in set (0.00 sec)
因此,有了这个新字段,我们可以得到这种格式的数据(在下面的 CSV 中说明):
"1";"1";"Books"
"11";"1.1";"Fiction"
"111";"1.1.1";"Science-Fiction"
"12";"1.2";"Self-Help"
"121";"1.2.1";"Motivational"
"1A";"1.10";"Textbooks"
"1e";"1.40";"Coloring Books"
"2";"2";"Music"
"21";"2.1";"Classical"
哪个MySQL会乐意为我们排序
mysql> SELECT * FROM `tree` ORDER BY `computer_readable`;
+-------------------+----------------+-----------------+
| computer_readable | human_readable | title |
+-------------------+----------------+-----------------+
| 1 | 1 | Books |
| 11 | 1.1 | Fiction |
| 111 | 1.1.1 | Science-Fiction |
| 12 | 1.2 | Self-Help |
| 121 | 1.2.1 | Motivational |
| 1A | 1.10 | Textbooks |
| 1e | 1.40 | Coloring Books |
| 2 | 2 | Music |
| 21 | 2.1 | Classical |
+-------------------+----------------+-----------------+
9 rows in set (0.00 sec)
希望这对您有所帮助。
关于mysql - 如何在 SQL 中订购分隔的数字字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8469016/