Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何在SQL中对分隔的数字字符串排序_Mysql_Sql - Fatal编程技术网

Mysql 如何在SQL中对分隔的数字字符串排序

Mysql 如何在SQL中对分隔的数字字符串排序,mysql,sql,Mysql,Sql,我需要对包含分隔数字组的字符串列进行正确排序,例如: 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.2之前列出1.10。这当然是意料之中的,但不幸的是,这不是我想要的,因为10>2。有没有一个有效的方法来获得我的订单?我正在使用My

我需要对包含分隔数字组的字符串列进行正确排序,例如:

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.2之前列出1.10。这当然是意料之中的,但不幸的是,这不是我想要的,因为10>2。有没有一个有效的方法来获得我的订单?我正在使用MySQL


请注意,我并不一定要对树使用这种编码,因此如果有一种不同的编码,那么就更容易排序,而不是随意建议。然而,该结构为我提供了一个很好的方法,可以在一个过程中恢复所有上游父节点或所有下游子节点,据我所知,这对于更典型的row/parent_row模型来说是不可行的。例如,给定id 1.2.1.4.5,我知道四个祖先分别是1、1.2、1.2.1和1.2.1.4,根据您的评论,每个节点的直接子节点可能不超过50个,所有子节点(直系后代和子节点的子节点)的id都将以1.2.1.4.5开头。

@Abiel,在这种情况下,62个子节点就足够了,正如@Bohemian在评论中所说的,我们可以使用计算机可读代码0-9A-Za-z,我们可以设置一个新的VARCHAR 255二进制列来帮助我们进行排序

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` )
);
您可能已经注意到,计算机可读列定义为二进制,因此每个节点最多可以有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)

希望这能有所帮助。

@Abiel,根据您的评论,每个节点可能没有超过50个直接子节点,在这种情况下,如@Bohemian在评论中所述,62个子节点就足够了,我们可以使用计算机可读代码0-9A-Za-z,我们可以设置一个新的VARCHAR 255二进制列来帮助我们进行排序

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` )
);
您可能已经注意到,计算机可读列定义为二进制,因此每个节点最多可以有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)

希望这有帮助。

这棵树有多深?有多少顶级节点?也没有上限?请看这个问题以获得更好的结构:@Riyono:实际上,树的深度可能不会超过10层。@Marc:谢谢,我可以使用这个结构。我唯一不喜欢的是,当单个节点发生变化时,它会导致其他节点的许多左右位置发生变化,从而导致大量的变化。由于某些原因,我可能会被迫存储对树的修订,因此在这方面,节点更改越少越好。实际上,父节点会有多少子节点?想知道我们是否可以采取不同的方法来保持这棵树有多深?有多少顶级节点?也没有上限?请看这个问题以获得更好的结构:@Riyono:实际上,树的深度可能不会超过10层。@Marc:谢谢,我可以使用这个结构。我唯一不喜欢的是,当单个节点发生变化时,它会导致其他节点的许多左右位置发生变化,从而导致大量的变化。由于某些原因,我可能会被迫存储对树的修订,因此在这方面,节点更改越少越好。实际上,父节点会有多少子节点?想知道我们是否可以采取不同的方法来保存这棵树