在树格式或添加水平MYSQL输出(亲子)(MYSQL output in tree format O

2019-06-24 15:21发布

下面是我在我的表。

为myTable

++++++++++++++++++++
Parent   +  Child
++++++++++++++++++++
  C1     +    G1
  C1     +    G2
  C1     +    G3
  G3     +    D1
  G3     +    D2
  C1     +    G4
  G4     +    D3
  G4     +    D4
  C2     +    G5
  C2     +    G6
  C2     +    G7
  C2     +    G8
 ++++++++++++++++++++

什么,我要的是下面使用MYSQL。

C1
  G1
  G2
  G3
    D1
    D2
  G4
    D3
    D4

C2
  G5
  G6
  G7
  G8

请让我知道这是可能的MYSQL。 输出是类似的树

更新1

如果我得到新的表像下面也未尝不可,这样我可以用这个例子 。

++++++++++++++++++++++++++++++++++++++++
Parent   +  Child   + PLevel  + CLevel
++++++++++++++++++++++++++++++++++++++++
  C1     +    G1    +   1    +   2
  C1     +    G2    +   1    +   2
  C1     +    G3    +   1    +   2
  G3     +    D1    +   2    +   3
  G3     +    D2    +   2    +   3
  C1     +    G4    +   1    +   2
  G4     +    D3    +   2    +   3
  G4     +    D4    +   2    +   3
  C2     +    G5    +   1    +   2
  C2     +    G6    +   1    +   2
  C2     +    G7    +   1    +   2
  C2     +    G8    +   1    +   2
++++++++++++++++++++++++++++++++++++++++

注:我已经开始水平1(例如,在我有从0开始的水平)。 如果我得到这个新表与级别从0开始的也很好。

Answer 1:

虽然你不能用一个单一的查询做,你可以用存储过程做...唯一的前置条件,则需要2个记录添加到您现有的样表,以表示“C1”和“C2” ARE顶层...添加一条记录里的“父”字段为空,而子级是“C1”,另一个为“C2”。 这将“准备”最顶层的父级。 后续层次的关联,否则,你的顶级层次结构的无起始“基础”。 它也需要一个“主键”栏(我已经在这个脚本“IDMyTable”这仅仅是1-X顺序创建,但是会假设你对你的表有一个自动递增列改为使用)。

我已经包括了所有输出列,以显示它是如何建成的,但这个程序的前提是要建立基于预期列输出表,但额外的下游保持分层表示,因为它是正在兴建。 以确保它们保持正确取向层变得更深,我concatinating的“ID”栏 - 你会看到它是如何工作的最终结果集。

然后,在最终的结果集,我是基于然而深层次的数据填充预空间。

循环将添加基于他们的父母在前面的结果集被发现的任何记录,但前提是尚未加入ID(防止重复)...

看到周期性顺序是如何不断地追加到,您可以运行通过无顺序的最后查询,看看每次迭代资格,以及如何添加应用之前的层级...

-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$

CREATE DEFINER=`root`@`localhost` PROCEDURE `GetHierarchy2`()
BEGIN
    -- prepare a hierarchy level variable 
    set @hierlvl := 00000;

    -- prepare a variable for total rows so we know when no more rows found
    set @lastRowCount := 0;

    -- pre-drop temp table
    drop table if exists MyHierarchy;

    -- now, create it as the first level you want... 
    -- ie: a specific top level of all "no parent" entries
    -- or parameterize the function and ask for a specific "ID".
    -- add extra column as flag for next set of ID's to load into this.
    create table MyHierarchy as
    select 
            t1.IDMyTable,
            t1.Child AS Parent,
            @hierlvl as IDHierLevel,
            cast( t1.IDMyTable as char(100)) FullHierarchy
        from
            MyTable t1
        where
                t1.Parent is null
            OR t1.Parent = '';


    -- how many rows are we starting with at this tier level
    set @lastRowCount := ROW_COUNT();

    -- we need to have a "primary key", otherwise our UPDATE
    -- statement will nag about an unsafe update command
    alter table MyHierarchy add primary key (IDMyTable);


    -- NOW, keep cycling through until we get no more records
    while @lastRowCount > 0 do

        -- NOW, load in all entries found from full-set NOT already processed
        insert into MyHierarchy
            select 
                    t1.IDMyTable,
                    t1.Child as Parent,
                    h1.IDHierLevel +1 as IDHierLevel,
                    concat_ws( ',', h1.FullHierarchy, t1.IDMyTable ) as FullHierarchy
                from
                    MyTable t1
                        join MyHierarchy h1
                            on t1.Parent = h1.Parent
                    left join
                        MyHierarchy h2
                            on t1.IDMyTable = h2.IDMyTable
                where
                    h2.IDMyTable is null;


        set @lastRowCount := row_count();

        -- now, update the hierarchy level
        set @hierLevel := @hierLevel +1;

    end while;


    -- return the final set now
    select 
            *, concat( lpad( ' ', 1 + (IDHierLevel * 3 ), ' ' ), Parent ) as ShowHierarchy
        from MyHierarchy
        order by FullHierarchy;

END


Answer 2:

MySQL和RDBMS的一般都不是很大,在这种类型的结构。 你可能会需要使用客户端的递归做到这一点。

如果递归限制为只有三个深,喜欢你的例子,你可以加入做到这一点,但它不是更深层次的树木非常可扩展性。



Answer 3:

首先创建钙水平的递归函数。

function fn_CalcLevel(int @ID) 
As Begin
  Declare @ParentID int
  Select @ParentID = ParentID From Table1 where ID = @ID

  IF (@ParentID IS NULL) Return 1 Else Return 1+fn_CalcLevel(@ParentID)
End

然后创建查询例如下面

Select *, fn_CalcLevel(Table1.ID) as Level
From Table1


Answer 4:

如果您重组表位,你可以使用这样的:

  SELECT Child,CONCAT(LPAD('',Clevel,' '),Child),etc from tablename

此次重组是你需要的根节点与您可以添加您自己的订货与父/子/ C级为希望获得序列的0父节点一行。

我知道这是一个几年前,但它可能挽救别人的一些努力!



文章来源: MYSQL output in tree format OR Adding level (Parent-Child)