Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySql在具有重复节点的闭包表中对分层数据进行排序_Mysql_Sorting_Tree_Hierarchical Data_Transitive Closure Table - Fatal编程技术网

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);
          
          或作为邻接列表:

          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);
          
          我可以生成宽度优先遍历(尽管5只作为孙子出现一次):

          但是,我尝试使用breadcrumbs进行深度优先遍历失败(它只显示了一次重复的节点,因为a.genderant对
          进行了分组
          ):

          是否可以使用闭包表表示输出深度优先遍历


          我应该使用另一种表示法吗?我不能使用递归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
                        列而不是
                        id
                        列来获得所需内容。

                        谢谢,Gordan。我也尝试过类似的方法——在a_d表中添加另一列“repeat count”,这样重复的节点就会是唯一的,但我无法实现这一点。这确实有效,但我需要考虑如何修改插入/更新/删除过程以维护表。
                        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