【问题标题】:Mysql - How to select all parents of a list of children?Mysql - 如何选择孩子列表的所有父母?
【发布时间】:2025-12-04 05:45:01
【问题描述】:

我有一个表,其中每条记录都包含他的父亲,这个层次结构可能最多有 6 个级别。下面的查询搜索名为“DEPARTMENT ABCD”的部门的所有父母。此查询完美运行。

SELECT D2.id, D2.name, D2.id_parent
FROM (
    SELECT
        @d AS _id,
        (SELECT @d := id_parent FROM department WHERE id = _id) AS id_parent,
        @l := @l + 1 AS level
    FROM
        (SELECT 
            @d := (select id from department where name = 'DEPARTMENT ABCD'), 
            @l := 0
        ) initial_level,
        department D
    WHERE @d <> 0
) D1
JOIN department D2 ON D1._id = D2.id
ORDER BY D1.level DESC;

但是,如果我想同时获取多个孩子的父母(在下面的查询中使用 like),我会收到错误:“错误代码:1242。子查询返回超过 1 行”。

出现错误“子查询返回超过 1 行”的查询:

SELECT D2.id, D2.name, D2.id_parent
FROM (
    SELECT
        @d AS _id,
        (SELECT @d := id_parent FROM department WHERE id = _id) AS id_parent,
        @l := @l + 1 AS level
    FROM
        (SELECT 
            @d := (select id from department where name like 'DEPARTMENT %A%'), 
            @l := 0
        ) initial_level,
        department D
    WHERE @d <> 0
) D1
JOIN department D2 ON D1._id = D2.id
ORDER BY D1.level DESC;

如何同时获得多个孩子的父母?

我在 SQL Fiddle 中添加了一个示例:http://sqlfiddle.com/#!9/f182fb/3

【问题讨论】:

  • 如果我得到你,你想显示项目的层次结构。如果是这样,您可以考虑选择此处所述的递归方法*.com/a/20216006/6435375
  • 感谢您的回答。我看到通知的链接和描述的方法以列的形式显示级别,也不支持寻找多个孩子的父母。
  • 你会为你的数据创建一个小的小提琴样本,甚至是一个假数据,以便我们测试结果吗? (sqlfiddle.com)
  • 嗨豪尔赫。我创建了一个小小提琴样本 (sqlfiddle.com/#!9/f182fb/3)。如果使用上面的查询就能模拟这种情况。提前谢谢!
  • 该特定错误消息意味着您正在运行只能返回一行数据的查询,例如你的@d := (select id ...)。由于您正在进行分配,因此只能分配一个值,而不是一组值。

标签: mysql sql


【解决方案1】:

鉴于层次结构可能最多有 6 个级别,我建议将表加入 6 次,以获取所选部门的所有祖先:

select     distinct id, name, id_parent
from       (
            select      d6.id_parent as id6,
                        d5.id_parent as id5,
                        d4.id_parent as id4,
                        d3.id_parent as id3,
                        d2.id_parent as id2,
                        d1.id_parent as id1,
                        d1.id        as id0
            from        department d1
            left join   department d2 on d2.id = d1.id_parent 
            left join   department d3 on d3.id = d2.id_parent 
            left join   department d4 on d4.id = d3.id_parent  
            left join   department d5 on d5.id = d4.id_parent  
            left join   department d6 on d6.id = d5.id_parent
            where       d1.name like 'DEPARTMENT A%'
           ) as h
inner join department d on d.id in (id0, id1, id2, id3, id4, id5, id6)
order by   1;

SQL fiddle

【讨论】:

  • 完美,谢谢!它工作得很好!我唯一担心的是,对于数千条记录的连接,查询是否会有点慢。你认为你可以带来性能问题,或者它无论如何都会很好地工作?提前谢谢!
  • 我认为性能不会成为问题。我实际上认为原始 SQL 中的相关子查询可能更多地消耗性能((SELECT @d := id_parent FROM department WHERE id = _id))。但这只是我的直觉,我可能是错的。
  • 好的,我明白了。非常感谢您的所有帮助和澄清!! =]