Mysql选择递归获取具有多个级别的所有子级

时间:2015-02-06 10:41:07

标签: mysql

我有一张桌子

 CREATE TABLE IF NOT EXISTS `Folder` (
    `idFolder` INT(11) NOT NULL AUTO_INCREMENT,
    `FolderName` VARCHAR(150) NOT NULL,
    `idFolderParent` INT(11) NULL,
    PRIMARY KEY (`idFolder`),
    CONSTRAINT `fk_1`
    FOREIGN KEY (`idFolderParent`)
    REFERENCES `Folder` (`idFolder`)
)

我用

填写此表
idFolder , FolderName , idFolderParent
   1           ADoc           Null  
   2           ADoc1           1  
   3           ADoc2           2
   4           ADoc3           3
   5           ADoc4           4
   6           ADoc5           5
   7           ADoc6           4

当选择idFolder = 1的文件夹时,应该返回此文件夹和子文件夹的所有子文件(2,3,4,5,6,7)

当我选择文件夹id = 4 ==> (5,7,6)

当我选择文件夹id = 3 ==> (4,5,6,7)

如何使用一个查询执行此操作?

THX

5 个答案:

答案 0 :(得分:18)

以前的解决方案都不适合我。只有父母按特定顺序保存到数据库中时,两者才有效。

我必须承认我并不完全理解查询的工作方式,但可以找到适合我的方式(至少比其他答案更好)。

第一个和第二个查询不起作用的数据是:

idFolder , FolderName , idFolderParent
   1           ADoc           Null  
   2           ADoc1           7  
   3           ADoc2           2
   4           ADoc3           3
   5           ADoc4          Null
   6           ADoc5           5
   7           ADoc6           5

如果您在此数据集中使用第一个和第二个查询,则对于ID 5,您只能获得结果' 6,7'。但如果你使用我的查询,你会得到:' 6,7,2,3,4'这是预期的结果。

我的版本:

SELECT GROUP_CONCAT(lv SEPARATOR ',') FROM (
SELECT @pv:=(SELECT GROUP_CONCAT(idFolder SEPARATOR ',') FROM Folder 
WHERE FIND_IN_SET(idFolderParent, @pv)) AS lv FROM Folder 
JOIN
(SELECT @pv:=5) tmp
) a;

希望它有所帮助。由于缺乏声誉,我无法评论或低估其他答案:(

答案 1 :(得分:11)

这是工作中的

SELECT GROUP_CONCAT(lv SEPARATOR ',') FROM (
SELECT @pv:=(SELECT GROUP_CONCAT(idFolder SEPARATOR ',') FROM Folder WHERE idFolderParent IN (@pv)) AS lv FROM Folder
JOIN
(SELECT @pv:=1)tmp
WHERE idFolderParent IN (@pv)) a;

在这里查看SQL FIddle:http://sqlfiddle.com/#!2/02b78/1

答案 2 :(得分:6)

请注意MySQL会对待

idFolderParent IN ('1, 2')

作为单个值,因此它等于:

idFolderParent IN ('1')

所以为了在列表上操作,你需要:

SELECT GROUP_CONCAT(lv SEPARATOR ',') FROM (
SELECT @pv:=(SELECT GROUP_CONCAT(idFolder SEPARATOR ',') FROM Folder WHERE
FIND_IN_SET(idFolderParent, @pv)) AS lv FROM Folder
JOIN (SELECT @pv:=1)tmp
WHERE idFolderParent IN (@pv)) a;

FIND_IN_SET

答案 3 :(得分:2)

如果您不想在结果中删除主要ID,那么它可能会起作用从查询中删除SELECT 4 Level UNION

SELECT GROUP_CONCAT(Level SEPARATOR',')FROM( 选择4级    联盟    SELECT @Ids:=(SELECT GROUP_CONCAT(idFolder SEPARATOR',')FROM folder WHERE FIND_IN_SET(idFolderParent,@ Ids))等级    来自folder    JOIN(SELECT @Ids:= 4)temp1 )temp2

在这里查看SQL FIddle:http://sqlfiddle.com/#!9/a2b4b3/312

答案 4 :(得分:0)

要获取特定父级的所有级别子级,您可以使用以下查询:

 select idFolder from (select * from Folder order by idFolderParent, idFolder) Folder, (select @pv := '1') initialisation where find_in_set(idFolderParent, @pv) > 0 and @pv := concat(@pv, ',', idFolder )