1

我正在使用物化路径在 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 paths.txt 
/foo
/foo/bar
/foo-it
/foo-it/boy

有什么方法可以让 MySQL 对树进行正确排序?以与 unix 的 sort 实用程序相同的方式对其进行排序?也许是不同的排序规则或什么?还是有什么其他技巧?

4

1 回答 1

2

尝试这个:

SELECT * FROM categories ORDER BY path + '/';

生产:

/foo-it
/foo-it/boy
/foo
/foo/bar

/foo排在后面,/foo-it因为/foo/在 之后/foo-

你可以摆弄一下,比如用排序-后出现的东西替换,而不是路径或文件名中允许的东西。/

SELECT * FROM categories ORDER BY replace(path,'-','?') + '/';

生产:

/foo
/foo/bar
/foo-it
/foo-it/boy
于 2017-01-18T11:55:52.370 回答