使用 mysql 的父子关系

Parent child relation using mysql

我有一个名为 relation 的样本 mysql table 如下:

ID  TypeID  Name         Parent_ID
----------------------------------
1    1      Parent        0
2    2      Child1        1
3    2      Child2        1
4    3      GrandChild1   2
5    3      GrandChild2   2
6    3      GrandChild3   2
7    3      GrandChild4   3
8    3      GrandChild5   3

如何使用 mysql 查询生成如下所示的报告。

ParentName  ChildName   GrandChildName
--------------------------------------
Parent      Child1      GrandChild1
Parent      Child1      GrandChild2
Parent      Child1      GrandChild3
Parent      Child2      GrandChild4
Parent      Child2      GrandChild5

可以通过

来实现
select rl.Name as 'ParentName', rl1.Name as 'ChildName',rl2.Name as 'GrandChildName'  from relation rl
INNER JOIN (select * from relation where TypeID=2) rl1 ON rl.ID=rl1.Parent_ID
INNER JOIN (select * from relation where TypeID=3) rl2 ON rl1.ID=rl2.Parent_ID

我想知道其他方法。

编辑:这是我在没有内部查询的情况下发现的另一种方法,如下所示,这是我真正想要实现的。

select rl.Name as 'ParentName', rl1.Name as 'ChildName',rl2.Name as 'GrandChildName'  from relation rl
INNER JOIN relation rl1 ON rl.ID=rl1.Parent_ID and rl1.TypeID=2
INNER JOIN relation rl2 ON rl1.ID=rl2.Parent_ID and rl2.TypeID=3

如果您担心此查询的性能,那么您可以检查 运行 上述查询在单词 "EXPLAIN".

之前的性能
    EXPLAIN select 
      rl.Name as 'ParentName', 
      rl1.Name as 'ChildName',
      rl2.Name as 'GrandChildName'  from relation rl
    INNER JOIN (select * from relation where TypeID=2) rl1 ON rl.ID=rl1.Parent_ID
    INNER JOIN (select * from relation where TypeID=3) rl2 ON rl1.ID=rl2.Parent_ID

如果您发现性能不是很好,那么您可以在 TypeID 上创建索引。

这里有一个link对mysql的解释:

http://www.sitepoint.com/using-explain-to-write-better-mysql-queries/

CREATE INDEX Idx_TypeID relation(TypeID);

并像下面这样更改上面的查询:

select rl.Name as 'ParentName', rl1.Name as 'ChildName',rl2.Name as 'GrandChildName'  
from relation rl
INNER JOIN (select * from relation where TypeID=2) rl1 ON rl.ID=rl1.Parent_ID
INNER JOIN (select * from relation where TypeID=3) rl2 ON rl1.ID=rl2.Parent_ID
WHERE rl.TypeID=1

注意:我在最后一行添加了一个 where 子句,以利用刚刚创建的索引 (Idx_TypeID)。 (性能变得更好。)

现在再次检查单词 "EXPLAIN" 之前的查询。这次你会得到更好的解释输出。美好的一天!

编辑:

可以避免子查询。感谢 mpsbhat 指出我之前遗漏的重点。 所以这是我直接从 mpsbhat 的 post:

中引用的查询
SELECT
  rl. NAME AS 'ParentName',
  rl1. NAME AS 'ChildName',
  rl2. NAME AS 'GrandChildName'
FROM
  relation rl
INNER JOIN relation rl1 ON rl.ID = rl1.Parent_ID
AND rl1.TypeID = 2
INNER JOIN relation rl2 ON rl1.ID = rl2.Parent_ID
AND rl2.TypeID = 3

如果您解释查询,它会显示出比以前更好的性能。