下面是我在我的表。
为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开始的也很好。
虽然你不能用一个单一的查询做,你可以用存储过程做...唯一的前置条件,则需要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
MySQL和RDBMS的一般都不是很大,在这种类型的结构。 你可能会需要使用客户端的递归做到这一点。
如果递归限制为只有三个深,喜欢你的例子,你可以加入做到这一点,但它不是更深层次的树木非常可扩展性。
首先创建钙水平的递归函数。
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
如果您重组表位,你可以使用这样的:
SELECT Child,CONCAT(LPAD('',Clevel,' '),Child),etc from tablename
此次重组是你需要的根节点与您可以添加您自己的订货与父/子/ C级为希望获得序列的0父节点一行。
我知道这是一个几年前,但它可能挽救别人的一些努力!