MySql在具有重复节点的闭包表中对分层数据进行排序
我有一个表示为闭包表的层次结构,如所述。我正在尝试编写一个查询,返回按深度优先遍历排序的节点。这将解决我的问题,但在我的结构中,一些节点出现多次,因为它们有多个父节点 我的示例数据如下所示:MySql在具有重复节点的闭包表中对分层数据进行排序,mysql,sorting,tree,hierarchical-data,transitive-closure-table,Mysql,Sorting,Tree,Hierarchical Data,Transitive Closure Table,我有一个表示为闭包表的层次结构,如所述。我正在尝试编写一个查询,返回按深度优先遍历排序的节点。这将解决我的问题,但在我的结构中,一些节点出现多次,因为它们有多个父节点 我的示例数据如下所示: 125354625< 如您所见,节点2出现两次,既作为根的子节点,也作为根的孙子节点。节点5两次显示为根的孙子(每次都有不同的父节点),然后再次显示为曾孙节点,因为它的父节点2是重复的 这将把数据设置为关闭表: CREATE TABLE ancestor_descendant ( ancestor in
- 1
- 2
- 5
- 3
- 5
- 4
- 6
- 2
- 5
- <
如您所见,节点2出现两次,既作为根的子节点,也作为根的孙子节点。节点5两次显示为根的孙子(每次都有不同的父节点),然后再次显示为曾孙节点,因为它的父节点2是重复的
这将把数据设置为关闭表:
或作为邻接列表:CREATE TABLE ancestor_descendant ( ancestor int NOT NULL, descendant int NOT NULL, path_length int NOT NULL ); INSERT INTO ancestor_descendant (ancestor, descendant, path_length) VALUES (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0),(6,6,0),(1,2,1),(1,3,1),(1,4,1), (2,5,1),(3,5,1),(4,6,1),(4,2,1),(1,5,2),(1,6,2),(1,2,2),(1,5,3),(4,5,2);
我可以生成宽度优先遍历(尽管5只作为孙子出现一次): 但是,我尝试使用breadcrumbs进行深度优先遍历失败(它只显示了一次重复的节点,因为a.genderant对CREATE TABLE parent_child ( parent int NOT NULL, child int NOT NULL ); INSERT INTO parent_child (parent, child) VALUES (1,2),(1,3),(1,4),(2,5),(3,5),(4,2),(4,6);
进行了分组
): 是否可以使用闭包表表示输出深度优先遍历
我应该使用另一种表示法吗?我不能使用递归CTE,因为我仅限于MySql(它没有实现它们)。我建议将节点
分为两个概念。一个是用于图形属性的唯一id(即id
列表)。第二个是您在输出上显示的内容祖先\后代
- 1
- 2
- 5
- 3
- 50
- 4
- 6
- 20
- 51
- <
然后创建映射表:
Id Value 1 1 2 2 20 2 3 3 4 4 5 5 50 5 51 5 6 6
然后,您可以通过连接回映射表并使用
列而不是value
列来获得所需内容。谢谢,Gordan。我也尝试过类似的方法——在a_d表中添加另一列“repeat count”,这样重复的节点就会是唯一的,但我无法实现这一点。这确实有效,但我需要考虑如何修改插入/更新/删除过程以维护表。id
SELECT a.descendant, GROUP_CONCAT(b.ancestor ORDER BY b.path_length DESC) AS breadcrumbs FROM ancestor_descendant a INNER JOIN ancestor_descendant b ON (b.descendant = a.descendant) WHERE a.ancestor = 1 GROUP BY a.descendant ORDER BY breadcrumbs; 1 1 2 1,1,4,1,4,1,2,2 5 1,1,4,1,4,1,3,2,3,2,5,5 3 1,3 4 1,4 6 1,4,6
Id Value 1 1 2 2 20 2 3 3 4 4 5 5 50 5 51 5 6 6
- 2
- 2