我有一张由fk parentId自引用的表。
给定一个id,我需要提取它的所有子节点
我知道图表只有三个级别:root,middleNode,leaf
所以我试过这个:
SELECT *
FROM table AS root
LEFT JOIN table AS middle
ON middle.parentId = root.id
LEFT JOIN table AS leaf
ON leaf.parentId = middle.id
WHERE root.id = 1
但是这样我每个节点都没有一行...
此外,此实现没有考虑到两件事:
答案 0 :(得分:0)
对于3个级别,您可以使用
SELECT * FROM
-- root
(
SELECT *
FROM your_table WHERE id = 1
) as root
UNION ALL
-- level1
(
SELECT * FROM your_table WHERE parentId = 1 )
)
UNION ALL
-- level2
(
SELECT * FROM your_table WHERE parentId IN (SELECT id FROM your_table WHERE parentId = 1 )
)
但是对于深度,我建议您实施常用方法,例如嵌套集模型(需要添加额外的列),请take a look on this
答案 1 :(得分:0)
如果你想从你所在的位置沿着树走下去,你可以使用临时表来做到这一点。
CREATE TABLE tempTable (id int, parentid int);
INSERT INTO tempTable (id, parentid)
SELECT id, parentID FROM tree WHERE id = @input;
SET @LastCount=0;
SELECT @Count = COUNT(1) FROM tempTable;
WHILE @LastCount != @Count DO
INSERT INTO tempTable (id, parentid)
SELECT id,parentid from tree where id in (SELECT parentid FROM TempTable) AND ID NOT IN (SELECT id FROM TempTable);
@LastCount = @Count;
SELECT @Count = COUNT(1) FROM tempTable;
END WHILE;
SELECT * FROM tempTable;
DROP tempTable;
这将循环遍历,继续沿着层次结构向下移动,添加当前在表中具有父级的行,只要这些行不存在,并且在不添加新行时结束循环(最后一个循环)行计数=当前循环行计数)这样做的好处是根本不关心层次结构的大小,它可以是3级或30级,也不关心你从哪里开始,它总是下降一层。 / p>
如果您想要包含该节点的整个层次结构,您可以在层次结构中循环,直到找到没有父节点的层次结构(如果您在同一个表中有多个树,例如多个带有过道的仓库,并且每个仓库顶层):
SET @next = @input;
WHILE @next IS NOT NULL DO
SET @topID = @next;
SELECT @next = parentID FROM tree WHERE id=@topID;
END WHILE
CREATE TABLE tempTable (id int, parentid int);
INSERT INTO tempTable (id, parentid);
SELECT id, parentID FROM table WHERE id = @topID;
SET @LastCount=0;
SELECT @Count = COUNT(1) FROM tempTable;
WHILE @LastCount != @Count DO
INSERT INTO tempTable (id, parentid)
SELECT id,parentid from tree where id in (SELECT parentid FROM TempTable) AND ID NOT IN (SELECT id FROM TempTable);
@LastCount = @Count;
SELECT @Count = COUNT(1) FROM tempTable;
END WHILE;
SELECT * FROM tempTable;
DROP tempTable;
这将运行到树的顶部,然后逐级循环回来。任何一个都可以在while循环中使用一个计数器变量来查找从你开始的点开始的相对级别。
SQLFiddle不允许其中一些函数适用于MySQL,但我确实有一个MsSQL小提琴显示此函数有效 - MsSql Fiddle