MySQL以层次结构返回所有记录

时间:2013-04-18 18:49:28

标签: mysql hierarchical-data

我有一个简单的分层表'群组'我存储每个孩子的父ID。

我尝试使用以下查询查询表组的每个成员:

SELECT groups.name  AS 'Group Name', 
       groups1.name AS 'Group1 Name' 
FROM   groups 
       LEFT JOIN groups groups1 
              ON groups.id = groups1.parent_id 
WHERE  groups.parent_id = 0 
ORDER  BY groups.id, 
          groups1.id 

我得到了:

|集团名称...................................... | Group1名称...... ......... |
| ------------------------------------------------- ------------------------- |
|资产............................................... |固定资产.............. |
|资产............................................... |流动资产.......... |
|资产............................................... |投资............... |
|负债和所有者权益............ |资本账户......... |
|负债和所有者权益............ |流动负债...... |
|收入............................................ |直接收入。 .......... |

但我真正想要的是每个节点的一条线,即使有一个孩子,即:。

|集团名称...................................... | Group1名称...... ......... |
| ------------------------------------------------- ------------------------- |
|资产............................................... | .................................. |
|资产............................................... |固定资产.............. |
|资产............................................... |流动资产.......... |
|资产............................................... |投资............... |
|负债和所有者权益............ | ................................ .... |
|负债和所有者权益............ |资本账户......... |
|负债和所有者权益............ |流动负债...... |
|收入............................................ | ... ............................... |
|收入............................................ |直接收入。 .......... |

有没有办法对查询或查询执行此操作?

2 个答案:

答案 0 :(得分:0)

不要将parent_id设置为0表示顶级条目,而是将parent_id设置为自身(即parent_id = id)。然后将顶层加入到包含其自身的所有“孩子”中。

SELECT parent.name AS `Group Name`, 
  IF(parent.id = child.id, '', child.name) AS `Group1 Name` 
FROM groups AS parent JOIN groups AS child 
  ON ((parent.id = child.parent_id))) 
WHERE parent.parent_id = parent.id 
ORDER BY parent.id, child.id

请注意,您不需要LEFT OUTER JOIN,因为保证至少有一个“孩子”。

您还可以使用我在Stack Overflow上的几篇文章中描述的Closure Table设计:

答案 1 :(得分:0)

这是一种为您提供一些额外字段的方法,但它需要这样做才能正确排序结果。如果你想稍微清理一下输出,你可以在技术上将另一个选择包围在这个选择的输出周围。

(
    SELECT groups.id AS parent_id, groups1.id AS child_id, groups.name  AS 'Group Name', 
       IF(LENGTH(groups1.name), groups1.name, '') AS 'Group1 Name' 
    FROM   groups 
    LEFT JOIN groups groups1 ON groups.id = groups1.parent_id 
    WHERE  groups.parent_id = 0
) 
UNION 
(
    SELECT groups.id AS parent_id, NULL AS child_id, groups.name  AS 'Group Name', '' AS 'Group1 Name' FROM groups WHERE groups.parent_id = 0
) 
ORDER BY parent_id, child_id