3

この参照 ( http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ ) を使用して MYSQL でツリー構造を表示しようとしていますが、同じテーブル内の 1 つの親でのみ機能することがわかります.
結合する別のテーブルがある場合、何もうまくいきません。例:

テーブルメニュー:

+----+--------+-------+
| id |  name  | order |
| 1  | Father |   0   |
| 2  | Father |   1   |
| 3  | Son    |   0   |
| 4  | Child  |   1   |
| 5  | Granson|   2   |
+----+--------+-------+

テーブル リレーション

+----+---------+-----------+
| id | menu_id | parent_id |
| 1  |    1    |    NULL   |
| 2  |    2    |    NULL   |
| 3  |    3    |     1     |
| 4  |    4    |     3     |
| 5  |    5    |     4     |
+----+---------+-----------+

選択を行う

SELECT child_menu.*, menu.* FROM menu, relations AS child_menu
WHERE menu.id = child_menu.menu_id
GROUP BY menu_id

私はこれを持っています:

+----+--------+-------+
| id |  name  | order |
| 1  | Father |   0   |
| 2  | Father |   1   |
| 3  | Son    |   0   |
| 4  | Child  |   1   |
| 5  | Granson|   2   |
+----+--------+-------+

同じSELECTで子供たちを順番に残そうとしています。
例で見たものから、親が同じテーブルにある場合にのみ機能します。
誰かが私を助けることができますか?ありがとうございました

編集:期待される出力:

+----+--------+-------+
| id |  name  | order |
| 1  | Father |   0   |
| 3  | Son    |   0   |
| 4  | Child  |   1   |
| 5  | Granson|   2   |
| 2  | Father |   1   |
+----+--------+-------+

I.E. Father
       Son
         Child
            Grandson
4

3 に答える 3

4

MySQL ユーザー定義関数を作成できる場合は、次のようなものを使用して、実行時に家系図を動的に作成できます。

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 ;

次に、次の SQL は、探しているシーケンスを提供する必要があります。

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 )
;

http://sqlfiddle.com/#!2/199c25/1で試してみてください。結果は次のとおりです。

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

少なくとも、これはあなたが求めているものだと思います。

実際のスキーマの更新

ユーザー定義関数:

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 ;

クエリ:

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 )
;

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
于 2013-11-20T21:53:20.550 に答える