递归 CTE - 获取后代(many-to-many 关系)

Recursive CTE - Get descendants (many-to-many relationship)

我有:

给定一棵描述系统如何由其通用部分组成的树(或更像是有向图)。现在让这个系统成为例如人类 body 和节点 body 部分。

因此,例如 3 可能是具有左叶和右叶(69)的肝脏,两叶中都有静脉(8)(也可以在肝脏的任何未指定位置找到,因此 8->3)但也可以在舌头中找到 (5)。肺 (7) - 位于胸部 (4) - 也有一个右叶,依此类推...(当然,肝脏中没有肺,还有一个6->7 是合理的,所以这个例子不是最好的,但你明白了。)

所以我在数据库中有这样的数据:

table: part
+----+------------+   id is primary key
| id | name       |
+----+------------+
|  1 | head       |
|  2 | mouth      |
|  3 | liver      |
|  4 | chest      |
|  5 | tongue     |
|  6 | left lobe  |
|  7 | lung       |
|  8 | veins      |
|  9 | right lobe |
+----+------------+

table: partpart
+-------+---------+   part&cont is primary key
| part  | cont    |   part is foreign key for part.id
+-------+---------+   cont is foreign key for part.id
|   2   |    1    |
|   3   |    1    |
|   5   |    2    |
|   6   |    3    |
|   7   |    3    |
|   7   |    4    |
|   8   |    3    |
|   8   |    5    |
|   8   |    6    |
|   8   |    9    |
|   9   |    3    |
|   9   |    7    |
+-------+---------+

我想达到的目标:

我想查询可以在部分 3 中找到的所有部分,并希望得到这样的结果:

result of query
+-------+---------+
| part  | subpart |
+-------+---------+
|   3   |    6    |
|   3   |    7    |
|   3   |    8    |
|   3   |    9    |
|   6   |    8    |
|   7   |    9    |
|   9   |    8    |
+-------+---------+

我觉得以这种所需的格式获得结果是不可行的,但将它作为类似的集合还是很棒的,因为我的目的是像这样为用户显示数据:

3
├─ 6
│  └─ 8
├─ 7
│  └─ 9
│     └─ 8
├─ 8
└─ 9
   └─ 8

我正在努力:

WITH RECURSIVE tree AS (

  SELECT part.id as part, partpart.cont (..where to define subpart?)
  FROM part JOIN partpart
  ON part.id = partpart.part
  WHERE part.id = 3

  UNION ALL

  SELECT part.id, partpart.cont
  FROM (part JOIN partpart
  ON part.id = partpart.part
  ), tree
  WHERE partpart.cont = tree.part

)

SELECT part, subpart FROM tree

这是我能做的最接近的,但当然行不通。

问题已解决,这是我需要的查询,我希望它也能帮助别人...

WITH RECURSIVE graph AS (
  SELECT
    p.id AS subpart,
    pp.cont AS part
  FROM part p JOIN partpart pp
  ON p.id = pp.part
  WHERE pp.cont = 3
  UNION ALL
  SELECT
    part.id,
    partpart.cont
  FROM (part JOIN partpart
  ON part.id = partpart.part
  ), graph WHERE partpart.cont = graph.subpart
)
SELECT part, subpart, FROM graph