在mysql中获取父/子/子关系

时间:2014-09-12 12:27:01

标签: mysql hierarchical-data

我有一张桌子'标签'包含以下字段(id,parent_id,name)。现在我在层次结构中设置了3个级别的限制,即:parent>孩子> subchild。子孙女不能再生孩子。所以我想要一个查询来检索记录,如:

父数据 (如果父母有孩子)孩子数据 (如果孩子有子项)子子数据

1 个答案:

答案 0 :(得分:1)

尝试类似:

SELECT tparent.id   AS parent_id, 
       tparent.name AS parent_name, 
       tchild1.id   AS child_id, 
       tchild1.name AS child_name, 
       tchild2.id   AS subchild_id, 
       tchild2.name AS subchild_name 
FROM   tags tparent 
       LEFT JOIN tags tchild1 
              ON tparent.id = tchild1.parent_id 
       LEFT JOIN tags tchild2 
              ON tchild1.id = tchild2.parent_id 

根据您的评论,您正在寻找以下输出:

ID | PARENT | NAME
 1 |      0 | family
 2 |      1 | male
 3 |      2 | boy1
 4 |      2 | boy2
 5 |      1 | female
 6 |      5 | girl1

我会假设ID不会总是按此顺序排列,如果它们存在,问题就解决了:)

我不确定您是否可以直接在SQL中实现此功能而不添加一些将用于订购的其他信息。例如,您可以添加另一列,以便连接父子子进程的id。类似的东西:

-- parent
SELECT CONCAT(LPAD(id, 6, '0'), '-000000-000000') AS order_info,
       id                                         AS id,
       parent_id                                  AS parent,
       name                                       AS name
FROM   tags
WHERE  parent_id = 0
UNION
-- child
SELECT CONCAT_WS('-', LPAD(tparent.id, 6, '0'), 
                      LPAD(tchild1.id, 6, '0'),
                      '000000'),
       tchild1.id,
       tparent.id,
       tchild1.name
FROM   tags tparent
       INNER JOIN tags tchild1
               ON tparent.id = tchild1.parent_id
WHERE  tparent.parent_id = 0
UNION
-- subchild
SELECT CONCAT_WS('-', LPAD(tparent.id, 6, '0'), 
                      LPAD(tchild1.id, 6, '0'),
                      LPAD(tchild2.id, 6, '0')),
       tchild2.id,
       tchild1.id,
       tchild2.name
FROM   tags tparent
       INNER JOIN tags tchild1
               ON tparent.id = tchild1.parent_id
       INNER JOIN tags tchild2
               ON tchild1.id = tchild2.parent_id
ORDER  BY 1

请参阅the fiddle说明这一点。

在这里,我将格式化ID以保持顺序一致。这意味着要知道id的最大长度(我在这里使用的长度为6),从id字段类型中猜测是微不足道的。