如何正确排序 SQL 中的物化路径?
How do I properly sort a materialized paths in SQL?
我正在使用物化路径在 SQl 中存储树结构(在我的例子中是 MySQL 5.7)。我将路径存储为斜杠分隔的 slug。我读过的所有教程都说按路径对行进行排序以按正确的顺序提取它,但是当部分路径具有相似的前缀时它似乎不起作用。
一些示例代码:
CREATE TABLE categories (
id int(11),
parent_id int(11) DEFAULT NULL,
slug varchar(255),
path varchar(255)
);
INSERT INTO categories VALUES
(1, null, 'foo', '/foo'),
(2, 1, 'bar', '/foo/bar'),
(3, null, 'foo-it', '/foo-it'),
(4, 3, 'boy', '/foo-it/boy');
现在,按路径排序时我得到了错误的顺序:
SELECT * FROM categories ORDER BY path;
输出:
+------+-----------+--------+-------------+
| id | parent_id | slug | path |
+------+-----------+--------+-------------+
| 1 | NULL | foo | /foo |
| 3 | NULL | foo-it | /foo-it |
| 4 | 3 | boy | /foo-it/boy |
| 2 | 1 | bar | /foo/bar |
+------+-----------+--------+-------------+
4 rows in set (0.00 sec)
这似乎是因为 - 在大多数(所有?)排序规则中先于 /。
疯狂的是,unix sort 命令行实用程序做了正确的事情。如果我将所有路径放在一个文件中并对其进行排序,我会得到正确的输出:
$ sort paths.txt
/foo
/foo/bar
/foo-it
/foo-it/boy
有什么方法可以使 MySQL 树正确排序吗?以与 unix 的排序实用程序相同的方式对其进行排序?也许是不同的归类之类的?或者还有其他技巧吗?
试试这个:
SELECT * FROM categories ORDER BY path + '/';
产生:
/foo-it
/foo-it/boy
/foo
/foo/bar
/foo
排在 /foo-it
之后,因为 /foo/
在 /foo-
之后。
您可以 fiddle 有点像将 -
替换为排序中 /
之后的内容,但不允许出现在路径或文件名中。
SELECT * FROM categories ORDER BY replace(path,'-','?') + '/';
产生:
/foo
/foo/bar
/foo-it
/foo-it/boy
我正在使用物化路径在 SQl 中存储树结构(在我的例子中是 MySQL 5.7)。我将路径存储为斜杠分隔的 slug。我读过的所有教程都说按路径对行进行排序以按正确的顺序提取它,但是当部分路径具有相似的前缀时它似乎不起作用。
一些示例代码:
CREATE TABLE categories (
id int(11),
parent_id int(11) DEFAULT NULL,
slug varchar(255),
path varchar(255)
);
INSERT INTO categories VALUES
(1, null, 'foo', '/foo'),
(2, 1, 'bar', '/foo/bar'),
(3, null, 'foo-it', '/foo-it'),
(4, 3, 'boy', '/foo-it/boy');
现在,按路径排序时我得到了错误的顺序:
SELECT * FROM categories ORDER BY path;
输出:
+------+-----------+--------+-------------+
| id | parent_id | slug | path |
+------+-----------+--------+-------------+
| 1 | NULL | foo | /foo |
| 3 | NULL | foo-it | /foo-it |
| 4 | 3 | boy | /foo-it/boy |
| 2 | 1 | bar | /foo/bar |
+------+-----------+--------+-------------+
4 rows in set (0.00 sec)
这似乎是因为 - 在大多数(所有?)排序规则中先于 /。
疯狂的是,unix sort 命令行实用程序做了正确的事情。如果我将所有路径放在一个文件中并对其进行排序,我会得到正确的输出:
$ sort paths.txt
/foo
/foo/bar
/foo-it
/foo-it/boy
有什么方法可以使 MySQL 树正确排序吗?以与 unix 的排序实用程序相同的方式对其进行排序?也许是不同的归类之类的?或者还有其他技巧吗?
试试这个:
SELECT * FROM categories ORDER BY path + '/';
产生:
/foo-it
/foo-it/boy
/foo
/foo/bar
/foo
排在 /foo-it
之后,因为 /foo/
在 /foo-
之后。
您可以 fiddle 有点像将 -
替换为排序中 /
之后的内容,但不允许出现在路径或文件名中。
SELECT * FROM categories ORDER BY replace(path,'-','?') + '/';
产生:
/foo
/foo/bar
/foo-it
/foo-it/boy