改变递归 CTE 生成的分层结果的顺序?
Altering the order of a hierarchical result generated by a Recursive CTE?
我正在使用 MySQL,我想知道是否可以更改递归 CTE 生成的结果的顺序。
我的 Table 有这些列:
|----------|----------|----------|----------|
| ID | parentID | title | Sort |
|----------|----------|----------|----------|
| 1 | null | Maria | 1 |
| 2 | 1 | John | 2 |
| 3 | 2 | Maria | 3 |
| 4 | 1 | Anthony | 1 |
| 5 | 4 | XXX | 1 |
| 6 | 4 | ... | 2 |
| 7 | 2 | ... | 2 |
| 8 | 2 | ... | 1 |
| 9 | 1 | ... | 3 |
我使用以下查询(我们不考虑排序列)
WITH RECURSIVE cte AS
(
SELECT ID, parentID, title, 0 AS depth, CAST(ID AS CHAR(200)) AS path
FROM categories WHERE ID = 1
UNION ALL
SELECT c.ID, c.parentID, c.title, cte.depth + 1, CONCAT(cte.path, ',', c.ID)
FROM categories c
JOIN cte ON cte.parentID = c.ID
WHERE FIND_IN_SET(c.ID, cte.path)=0
)
SELECT * FROM cte ORDER BY cte.path
接下来是我们从上述查询中获得的分层结果(以 ID 表示)。我们完全忽略排序列。
Hierarchy Depth
1 2 3
| | |
IDs
1
2
3
7
8
4
5
6
9
我想要的是考虑 sort
列并创建以下顺序的查询。从您所看到的 4、2、9 的 ID 分别具有排序编号 1、2、3,并且在深度级别 2 的结果中会考虑该顺序,在所有深度级别中也类似。
Hierarchy Depth
1 2 3
| | |
IDs
1
4
5
6
2
8
7
3
9
正在寻找对我的查询的编辑以实现上述结果。
我觉得你可以根据排序的优先级构造排序路径。不幸的是,这些似乎在不同的行上重复,所以我也将包括原始 id:
WITH RECURSIVE cte AS (
SELECT ID, parentID, title, 0 AS depth, CAST(ID AS CHAR(200)) AS path,
CONCAT(sort, '-', id) as sort_path
FROM categories
WHERE ID = 2
UNION ALL
SELECT c.ID, c.parentID, c.title, cte.depth + 1, CONCAT(cte.path, ',', c.ID) ,
CONCAT(cte.sort_path, c.sort, '-', c.id, ',') as sort_path
FROM categories c JOIN
cte
ON cte.parentID = c.ID
WHERE FIND_IN_SET(c.ID, cte.path) = 0
)
SELECT *
FROM cte
ORDER BY sort_path;
Here 是一个 db<>fiddle。对于您的示例数据,这只会深入一层,因此它实际上并不能说明这是否有效。此外,这假定 ID 和排序优先级永远不会超过一个字符——顺便说一下,您的查询也是如此。
我正在使用 MySQL,我想知道是否可以更改递归 CTE 生成的结果的顺序。
我的 Table 有这些列:
|----------|----------|----------|----------|
| ID | parentID | title | Sort |
|----------|----------|----------|----------|
| 1 | null | Maria | 1 |
| 2 | 1 | John | 2 |
| 3 | 2 | Maria | 3 |
| 4 | 1 | Anthony | 1 |
| 5 | 4 | XXX | 1 |
| 6 | 4 | ... | 2 |
| 7 | 2 | ... | 2 |
| 8 | 2 | ... | 1 |
| 9 | 1 | ... | 3 |
我使用以下查询(我们不考虑排序列)
WITH RECURSIVE cte AS
(
SELECT ID, parentID, title, 0 AS depth, CAST(ID AS CHAR(200)) AS path
FROM categories WHERE ID = 1
UNION ALL
SELECT c.ID, c.parentID, c.title, cte.depth + 1, CONCAT(cte.path, ',', c.ID)
FROM categories c
JOIN cte ON cte.parentID = c.ID
WHERE FIND_IN_SET(c.ID, cte.path)=0
)
SELECT * FROM cte ORDER BY cte.path
接下来是我们从上述查询中获得的分层结果(以 ID 表示)。我们完全忽略排序列。
Hierarchy Depth
1 2 3
| | |
IDs
1
2
3
7
8
4
5
6
9
我想要的是考虑 sort
列并创建以下顺序的查询。从您所看到的 4、2、9 的 ID 分别具有排序编号 1、2、3,并且在深度级别 2 的结果中会考虑该顺序,在所有深度级别中也类似。
Hierarchy Depth
1 2 3
| | |
IDs
1
4
5
6
2
8
7
3
9
正在寻找对我的查询的编辑以实现上述结果。
我觉得你可以根据排序的优先级构造排序路径。不幸的是,这些似乎在不同的行上重复,所以我也将包括原始 id:
WITH RECURSIVE cte AS (
SELECT ID, parentID, title, 0 AS depth, CAST(ID AS CHAR(200)) AS path,
CONCAT(sort, '-', id) as sort_path
FROM categories
WHERE ID = 2
UNION ALL
SELECT c.ID, c.parentID, c.title, cte.depth + 1, CONCAT(cte.path, ',', c.ID) ,
CONCAT(cte.sort_path, c.sort, '-', c.id, ',') as sort_path
FROM categories c JOIN
cte
ON cte.parentID = c.ID
WHERE FIND_IN_SET(c.ID, cte.path) = 0
)
SELECT *
FROM cte
ORDER BY sort_path;
Here 是一个 db<>fiddle。对于您的示例数据,这只会深入一层,因此它实际上并不能说明这是否有效。此外,这假定 ID 和排序优先级永远不会超过一个字符——顺便说一下,您的查询也是如此。