【问题标题】:Mysql select recursive get all child with multiple levelMysql select recursive get all child with multiple level
【发布时间】:2015-04-06 11:37:42
【问题描述】:

我有一张桌子

 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

when select a folder with idFolder=1, it should be return all child for this folder and subchild folder(2, 3, 4, 5 ,6 ,7)

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

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

如何用一个查询做到这一点?

谢谢

【问题讨论】:

标签: mysql


【解决方案1】:

这是工作中的一个

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

【讨论】:

  • 感谢此解决方案.. 我需要将此查询的结果用于其他查询,例如:select * from xxx where idFolder IN(您的查询)! ..有可能吗?!
  • @Dev Dev 提出了相同的查询以获得所需的结果
  • 这是一个很好的解决方案。我想知道如何在我将它用于角色的子选择中使用它。例如:
    代理:
    ID,用户名,密码,角色。
    角色:
    姓名,Parent_Name

    我可以使用原始查询得到孩子的角色,但我想做类似的事情:
  • @Dheerendra Kulkarni 如果我再添加一行作为 INSERT INTO folder (id_folder,FolderName,idFolderParent) VALUES (8,'ADoc7', '7') 将不起作用) 你的查询只返回 5,7,6 但实际结果是 5,6,7,8
【解决方案2】:

注意 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

【讨论】:

  • 但仍然没有给出完美的结果。
  • 最后一行应该是“WHERE FIND_IN_SET(idFolderParent, @pv) a;”
【解决方案3】:

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

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

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

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;

希望它可以帮助某人。由于缺乏声誉,我无法评论或否决其他答案:(

【讨论】:

  • 这个其实更好,因为它返回所有同级的孩子。谢谢!
  • 这实际上分配得更好,因为它允许您使用与孩子相比具有更高和更低 id 的父母。如果 5 有一个也是孩子的父母,它甚至可以工作。我交换了 idFolder 和 idFolderParent 以仅获取父母(而不是父母的孩子)。
  • 这个有效。现在我只需要克服字符限制。很好的查询谢谢
  • @agentprovocateur 你应该使用 SET SESSION group_concat_max_len = 1000000;紧接在查询之前以增加字符限制。
【解决方案4】:
select  idFolder, FolderName, idFolderParent
                                from (select * from Folder order by idFolderParent, idFolder) folders_sorted,
                                (select @pv := 1) initialisation
                                where   find_in_set(idFolderParent, @pv) > 0
                                and @pv := concat(@pv, ',', idFolder)

@pv := 1 是您当前的文件夹 ID。我认为这是更好的解决方案。

Dheerendra Kulkarni 的回答在下面给出了不同排序规则的这个错误。我希望这会对某人有所帮助。

排序规则的非法混合 (utf8_general_ci,IMPLICIT) 和 (utf8_unicode_ci,IMPLICIT) 用于操作“=”

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;

【讨论】:

  • 嗨@Oğuz Can Sertel。我使用并成功实施的第一个查询。谢谢你。但是想要更多关于我想显示具有特定数据的孩子 id 的信息。你能帮帮我吗?
【解决方案5】:

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

 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 )

【讨论】:

    【解决方案6】:

    如果您不想将结果中的主 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 加入 (SELECT @Ids := 4) temp1 ) 温度2

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-20
      • 1970-01-01
      • 1970-01-01
      • 2010-09-23
      • 2015-05-17
      • 2011-08-11
      • 1970-01-01
      相关资源
      最近更新 更多