我需要正确排序包含分隔数字组的字符串列,例如:
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
的孩子。树可以任意深度,因此每个条目中的句点数量本身没有上限(尽管实际上列上的字符限制将强制执行此操作)。
我遇到的问题是SQL中的标准ORDER BY
操作会在1.10
之前列出1.2
。这当然是预期的,但不幸的是不是我想要的,因为10 > 2
。有没有一种有效的方式来获得我的订单?我正在使用MySQL。
请注意,我不一定要将这种编码用于树,因此如果有一种不同的编码比订购它更容易订购。但是,这个结构给我提供的一个好处是在一次传递中恢复所有上游父节点或所有下游子节点的简单方法,这不适用于更典型的row / parent_row模型(目前为止)我所知)。例如,给定身份1.2.1.4.5
我知道四个祖先是1
,1.2
,1.2.1
和1.2.1.4
,以及所有孩子(包括直系后代和儿童的孩子)的ID将以1.2.1.4.5.
开头。
答案 0 :(得分:0)
@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)
希望这有帮助。