MySQL Tree ordered by parent and child

前端 未结 3 1124
[愿得一人]
[愿得一人] 2020-12-10 22:18

I\'m trying to display a tree structure in MYSQL with this reference (http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/) and I\'m seeing that only works w

3条回答
  •  庸人自扰
    2020-12-10 22:44

    If you can create a MySQL User Defined Function, then you can dynamically create your family tree at execution time using something like the following:

    DELIMITER //
    
    CREATE FUNCTION fnFamilyTree ( id INT ) RETURNS TEXT
    BEGIN
       SET @tree = '';
       SET @qid = id;
       WHILE (@qid > 0) DO
          SELECT IFNULL(r.parent_id,-1),m.ordr INTO @pid,@ordr FROM Relations r JOIN Menu m ON m.id = r.id WHERE r.id = @qid LIMIT 1;
          SET @tree = CONCAT(@ordr,' ',@tree);
          SET @qid = @pid;
       END WHILE;
       RETURN RTRIM(@tree);
    END//
    
    DELIMITER ;
    

    Then the following SQL should give you the sequence you are seeking:

    SELECT m.id
          ,m.name
          ,r.parent_id
          ,fnFamilyTree( r.id )
      FROM Relations r
      JOIN Menu m
        ON m.id = r.menu_id
     ORDER BY fnFamilyTree( r.id )
    ;
    

    Try it at http://sqlfiddle.com/#!2/199c25/1. Results are:

    ID  NAME            PARENT_ID        FNFAMILYTREE( R.ID )
    1   Father          (null)           0
    3   Son             1                0 0
    4   Child           3                0 0 1
    5   Granson         4                0 0 1 2
    2   Father          (null)           1
    

    At least, I think this is what you're after.

    Update for actual schema

    User Defined Function:

    DELIMITER //
    
    CREATE FUNCTION fnFamilyTree ( id INT ) RETURNS TEXT
    BEGIN
       SET @tree = '';
       SET @qid = id;
       WHILE (@qid > 0) DO
          SELECT IFNULL(r.`menu_master_id`,-1),m.`order` INTO @pid,@order FROM `menu_has_menu_master` r JOIN `menu` m ON m.`id` = r.`menu_id` WHERE r.`menu_id` = @qid LIMIT 1;
          SET @tree = CONCAT(LPAD(@order,5,'0'),' ',@tree);
          SET @qid = @pid;
       END WHILE;
       RETURN RTRIM(@tree);
    END
    //
    
    DELIMITER ;
    

    Query:

    SELECT m.id
          ,m.name
          ,r.menu_master_id
          ,fnFamilyTree( r.menu_id )
      FROM menu_has_menu_master r
      JOIN menu m
        ON m.id = r.menu_id
     ORDER BY fnFamilyTree( r.menu_id )
    ;
    

    Results at http://sqlfiddle.com/#!2/cb0384

    ID      NAME                  MENU_MASTER_ID    FNFAMILYTREE( R.MENU_ID )
    8       Dashboard             (null)            00001
    6       Seções do Site      (null)            00002
    7       Home                  6                 00002 00003
    14      Catalogos             6                 00002 00004
    15      Marcas                14                00002 00004 00004
    16      Categoria 1           14                00002 00004 00006
    9       Arquivos              (null)            00007
    1       Administração       (null)            00127
    3       Usuarios              1                 00127 00001
    5       Secões do iPocket    1                 00127 00001
    13      Default Setups        1                 00127 00002
    4       Logs                  1                 00127 00003
    

提交回复
热议问题