英文:
Number branches in a tree structure with MySQL
问题
我明白你的需求是将树状结构转换为矩阵结构,并且你想知道如何在递归函数中计算Branch。你可以使用以下方法在递归查询中计算Branch:
WITH RECURSIVE tree AS
(
SELECT CAST(Node AS CHAR(255)) AS Path, 1 AS Branch, 1 AS Level, Node, Data
FROM treestructure t WHERE Node = 10
UNION ALL
SELECT CONCAT(Path, '.', t2.Node) AS Path,
CASE WHEN LENGTH(Path) < LENGTH(tree.Path) THEN Branch + 1 ELSE Branch END,
Level + 1,
t2.Node,
t2.Data
FROM treestructure t2
INNER JOIN tree ON t2.Parent = tree.Node
)
SELECT * FROM tree
ORDER BY Path;
上述代码中,我在递归查询中使用了CASE语句来计算Branch。如果新的路径(Path)较短,说明它是一个新的分支,所以我们将Branch加1。这应该能够帮助你在结果中正确计算Branch。
希望这能帮助你完成树结构到矩阵结构的转换。如果你有其他问题,请随时提出。
英文:
My task is to transform a tree structure to a matrix structure in order to present it in a report.
I'm using Delphi 11.3, TADOQuery and MySQL version 8.
The tree structure that I whant to transform to a matrix look like this showing the node Id and it's data.
coming from table treestructure where Nodes and Parents are identified with an Id,
Table treestructure
Idx | Node | Parent | Data |
---|---|---|---|
1 | 10 | NULL | AA |
2 | 20 | 10 | BB |
3 | 30 | 20 | CC |
4 | 40 | 30 | DD |
5 | 50 | 20 | EE |
6 | 60 | 50 | FF |
7 | 70 | 20 | GG |
Where the Row in my coming matrix is the number of the branch in the tree as showed by numbers within () below:
To get the data to the matrix I use a RECURSIVE call like:
WITH RECURSIVE tree AS
(
SELECT CAST(Node AS CHAR(255)) AS Path, 1 AS Branch, 1 AS Level, Node, Data
FROM treestructure t WHERE Id = 10
UNION ALL
SELECT CONCAT(Path,".",t2.Node) AS Path,
Branch // How to count up the Branch????,
Level + 1,
t2.Node,
t2.Data
FROM treestructure t2
INNER JOIN tree ON t2.Parent = tree.Node
)
SELECT * FROM tree
ORDER BY Path
which give me following result that I can transform to my matrix by using Branch and Level in combination.
Path | Branch | Level | Node | Parent | Data |
---|---|---|---|---|---|
10 | 1 | 1 | 10 | NULL | AA |
10,20 | 1 | 2 | 20 | 10 | BB |
10,20,30 | 1 | 3 | 30 | 20 | CC |
10,20,30,40 | 1 | 4 | 40 | 30 | DD |
10,20,50 | 2 | 3 | 50 | 20 | EE |
10,20,50,60 | 2 | 4 | 60 | 50 | FF |
10,20,70 | 3 | 2 | 70 | 20 | GG |
But my problem is that I can't find out how to calculatet or count up Branch within the recursive function.
One factor to use could be when path is shorter than the previous path then count upp branch with one. But how to do that in a query?
The final result will look like below after transforming the result above.
Branch | c1 | c2 | c3 | c4 |
---|---|---|---|---|
1 | AA | BB | CC | DD |
2 | EE | FF | ||
3 | GG |
答案1
得分: 1
...我的问题是我不知道如何计算或计数分支...
WITH RECURSIVE tree AS
(
SELECT CAST(Node AS CHAR(255)) AS Path, 1 AS Branch, 1 AS Level, Node, Data
FROM treestructure t WHERE Node = 10
UNION ALL
SELECT CONCAT(Path, ",", t2.Node) AS Path,
0 Branch ,
Level + 1,
t2.Node,
t2.Data
FROM treestructure t2
INNER JOIN tree ON t2.Parent = tree.Node
)
select replace(path, ',', '.') path, level, node, data,
sum(ifnull(mrk, 1)) over (order by path) branch
from (
select path, level, node, data,
1-sign(find_in_set(lag(node) over (order by path), path)) mrk
FROM tree ) t
ORDER BY Path
- 在递归查询中使用逗号而不是点(或者在递归中创建另一列,用逗号分隔),
- 我们需要这个逗号来使用
find_in_set
。每当前一节点(lag
)在当前行路径中不存在时,这意味着它是新分支,此行标记为1mrk
。 - 使用分析求和来计算标记行数。这个总和就是您的
branch
值。 - 现在您已经有了一切来基于
level
和branch
的值创建数据透视表, - 如果需要,替换路径中的逗号为点。
英文:
...my problem is that I can't find out how to calculate or count up Branch...
WITH RECURSIVE tree AS
(
SELECT CAST(Node AS CHAR(255)) AS Path, 1 AS Branch, 1 AS Level, Node, Data
FROM treestructure t WHERE Node = 10
UNION ALL
SELECT CONCAT(Path,",",t2.Node) AS Path,
0 Branch ,
Level + 1,
t2.Node,
t2.Data
FROM treestructure t2
INNER JOIN tree ON t2.Parent = tree.Node
)
select replace(path,',','.') path, level, node, data,
sum(ifnull(mrk, 1)) over (order by path) branch
from (
select path, level, node, data,
1-sign(find_in_set(lag(node) over (order by path), path)) mrk
FROM tree ) t
ORDER BY Path
- Use comma instead of dot in recursive query (or make another column in recursion, separated with commas),
- we need this comma to use
find_in_set
. Whenever previous node (lag
) is absent in current row path it means it is new branch, this row is marked as 1mrk
- use analytic sum to count marked rows. This sum is your
branch
value. - now you have everything to make pivot based on values
level
andbranch
, - replace commas in path with dots if needed.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论