【问题标题】:get a recursive parent list获取递归父列表
【发布时间】:2011-11-26 00:45:43
【问题描述】:

使用 MySQL,我想从具有这样的字段结构的表中返回父列表。 ID,PARENTID,NAME(标准父子层次结构)。我想遍历“向上”树以返回所有“父母”的列表。

我意识到“嵌套集”可能是处理此问题的更好方法 - 但目前我无法更改数据的结构。我会考虑在未来这样做。目前 - 我的数据集实际上将包含几个级别的深度 - 没什么疯狂的......可能是 2-5,所以我的递归命中不应该“太昂贵”。

我已经查看了SQL Server get parent list 中提出的解决方案 - 但是这个语法在 mySQL 中很糟糕...

有没有人举例说明如何做到这一点?

@kevin - 谢谢链接 - 但我仍然得到错误。 ("每个派生表都必须有自己的别名")

这就是我所做的(修改文章上方的语法形式 - 以“适应”MySQL)——我显然错过了一些东西......

SELECT parents.*
FROM  (
    SELECT taskID,  task,  parentID,  0 as level
    FROM   tasks
    WHERE taskidID = 9147
    UNION ALL
    SELECT  taskID, task,  parentID,  Level + 1 
    FROM   tasks
    WHERE  taskID = (SELECT parentID FROM parents ORDER BY level DESC LIMIT 1)
    )

想法???

示例:

ID      PARENTID    NAME
9146    0       thing1
9147    0       thing2
9148    9146        thing3
9149    9148        thing4
9150    0       thing5
9151    9149        thing6

查询“thing3”的父母 返回“9148,9146”

查询“thing6”的父母 返回“9149,9148,9146,0”

【问题讨论】:

  • 看到这个类似的问题:stackoverflow.com/questions/1382573/…
  • @Kevin 我认为它与这个问题没有任何关系。
  • @karolis - 它“有点”相关,我知道他指点我的地方..见上面的编辑...
  • @jpmyob 所以为那个表添加一个别名,例如as my_alias。但是在任何情况下都不能为 MySQL 重写 SQL 服务器的查询,因为 MySQL 不支持递归子查询。如果您不想将查询限制在几个级别,那么您需要创建一个存储函数或过程。

标签: mysql sql recursion


【解决方案1】:

在这里,我为你做了一个小功能,我在我的数据库(MAMP)中检查了它,它工作正常

use mySchema;
drop procedure if exists getParents;

DELIMITER $$
CREATE PROCEDURE getParents (in_ID int)
BEGIN
DROP TEMPORARY TABLE IF EXISTS results;
DROP TEMPORARY TABLE IF EXISTS temp2;
DROP TEMPORARY TABLE IF EXISTS temp1;

CREATE TEMPORARY TABLE temp1 AS
  select distinct ID, parentID
    from tasks
    where parentID = in_ID;

create TEMPORARY table results AS
  Select ID, parentID from temp1;

WHILE (select count(*) from temp1) DO
  create TEMPORARY table temp2 as
    select distinct ID, parentID 
      from tasks 
      where parentID in (select ID from temp1);

  insert into results select ID, parentID from temp2;
  drop TEMPORARY table if exists temp1;
  create TEMPORARY table temp1 AS
    select ID, parentID from temp2;
  drop TEMPORARY table if exists temp2;

END WHILE;


select * from results;

DROP TEMPORARY TABLE IF EXISTS results;
DROP TEMPORARY TABLE IF EXISTS temp1;

END $$
DELIMITER ;

此代码会将所有父级返回到任意深度。 您显然可以在结果中添加任何其他字段

像这样使用它

call getParents(9148)

例如

【讨论】:

  • 您可以使用 4 个空格代替 <pre><code> 来突出显示您的代码。
  • 这个函数看起来更像是返回一个ID的孩子
【解决方案2】:

在本例中,我们向上检查 5 个级别:

select 
    t1.parentid, t2.parentid, t3.parentid, t4.parentid, t5.parentid
from
    tableName t1
    left join tableName t2 on t1.parentid = t2.id
    left join tableName t3 on t2.parentid = t3.id
    left join tableName t4 on t3.parentid = t4.id
    left join tableName t5 on t4.parentid = t5.id
where
    t1.name = 'thing3'

【讨论】:

  • 在阅读了问题中的编辑后,OP 正在尝试处理递归 SQL(两个选择由 UNION ALL 连接),而不是像您这样的固定五级树。
  • @Louis 是的,但是 MySQL 不支持递归查询。此外,OP 说:我的数据集实际上将包含几个层次的深度。所以这可能是某种解决方案,因为它最多可用于 5 个级别。另一种方法是编写存储函数/过程。
  • @louis - 不完全是,我提供了工会,因为它来自处理一系列父母问题的“其他帖子”......无论如何 - 它不起作用......并且这可能 - 我将不得不在上下文中尝试它。谢了。
猜你喜欢
  • 2018-10-07
  • 2022-01-20
  • 1970-01-01
  • 2022-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-30
相关资源
最近更新 更多