【问题标题】:How do I select only one generation of a hierarchical tree using an table parent child relation with SQL?如何使用带有 SQL 的表父子关系仅选择一代层次树?
【发布时间】:2015-11-22 19:35:12
【问题描述】:

假设有一个名为 people 的表,其中包含以下列:

  • person_id(整数)
  • parent_person_id(整数)
  • 名称(varchar)

现在,假设表格已被填充,名称值只是字母(A、B、C、D ...)。考虑到每个人的父母,我们最终得到一棵像下面这样的分层树。值的格式为:

person_id、parent_person_id、姓名

  • 1, 1, A
  • 2、2、B
    • 3、2、C
      • 4、3、D
    • 5、2、E
      • 6、5、F
        • 7、6、G
        • 8、6、H

考虑上面的结构,A & B 为第一代,C & E 为第二代,D & F 为第三代,G & H 为第四代。对于第一代元素,parent_person_id 等于元素的 person_id。

我需要编写一个查询,允许我从树的某一代(第一、第二、第三、第四等)中选择名称。结果,我可以得到一个包含某一代用户姓名的表格。例如:

第一代

person name  |  parent name
A            |  A
B            |  B

第二代

person name  |  parent name
C            |  B
E            |  B

第三代

person name  |  parent name
D            |  C
F            |  E

第四代

person name  |  parent name
G            |  F
H            |  F

我想传递一个参数来定义每一代都应该在以下查询中列为子代。

SELECT
    child.name as 'person name',
    parent.name as 'parent name'
FROM
    people as child
JOIN 
    people as parent
ON 
    child.parent_person_id = parent.person_id
WHERE
    -- I NEED HELP HERE :)
;

有人对我如何实现这一目标有任何想法吗?欢迎任何帮助。

【问题讨论】:

  • Vinicius,我认为这个问题/答案可以帮助你stackoverflow.com/questions/5522478/sql-query-for-tree-table
  • 您能否提供一个包含您要查找的结果的表格?
  • @TomasoAlbinoni,我在问题中添加了一些结果表。请注意,每一代都会产生不同的结果。我可以把它全部放在一张桌子上,但我正在寻找每一代的桌子。
  • 可能的世代数是否有上限?
  • 理想情况下不会有最大值,但如果这样更容易,我会去 4 代。

标签: mysql sql


【解决方案1】:

这样冗长难看而且会很慢,而且只限4代,不过不知道还能怎么办。

SELECT person_name, parent_name FROM

    (SELECT child1.name AS person_name, parent1.name AS parent_name, '1' AS generation
    FROM people as child1
    JOIN people as parent1
    ON child1.parent_person_id = parent1.person_id AND child1.parent_person_id = child1.person_id

    UNION

    SELECT child2.name AS person_name, parent2.name AS parent_name, '2' AS generation
    FROM people as child2
    JOIN people as parent2
    ON child2.parent_person_id = parent2.person_id AND child2.parent_person_id <> child2.person_id AND parent2.parent_person_id = parent2.person_id

    UNION

    SELECT child3.name AS person_name, parent3.name AS parent_name, '3' AS generation
    FROM people as child3
    JOIN people as parent3
    ON child3.parent_person_id = parent3.person_id AND parent3.parent_person_id <> parent3.person_id
    JOIN people as grandparent1
    ON parent3.parent_person_id = grandparent1.person_id AND grandparent1.parent_person_id = grandparent1.person_id

    UNION

    SELECT child4.name AS person_name, parent4.name AS parent_name, '4' AS generation
    FROM people as child4
    JOIN people as parent4
    ON child4.parent_person_id = parent4.person_id AND parent4.parent_person_id <> parent4.person_id
    JOIN people as grandparent2
    ON parent4.parent_person_id = grandparent2.person_id AND grandparent2.parent_person_id <> grandparent2.person_id
    JOIN people as greatgrandparent
    ON grandparent2.parent_person_id = greatgrandparent.person_id AND greatgrandparent.parent_person_id = greatgrandparent.person_id
    ) AS tree

WHERE generation = ?

【讨论】:

  • 这工作正常。我为子查询添加了一个别名以避免错误 1248。其他错误是第 2 代,它也返回第 1 代。
  • 感谢您的编辑。我已经修改了第 2 代以排除第 1 代。
猜你喜欢
  • 2011-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-09
  • 1970-01-01
相关资源
最近更新 更多