递归 CTE - 获取后代(many-to-many 关系)
Recursive CTE - Get descendants (many-to-many relationship)
我有:
给定一棵描述系统如何由其通用部分组成的树(或更像是有向图)。现在让这个系统成为例如人类 body 和节点 body 部分。
因此,例如 3
可能是具有左叶和右叶(6
和 9
)的肝脏,两叶中都有静脉(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
我有:
给定一棵描述系统如何由其通用部分组成的树(或更像是有向图)。现在让这个系统成为例如人类 body 和节点 body 部分。
因此,例如 3
可能是具有左叶和右叶(6
和 9
)的肝脏,两叶中都有静脉(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