【问题标题】:Recursive CTE - Get descendants (many-to-many relationship)递归 CTE - 获取后代(多对多关系)
【发布时间】:2017-12-12 19:30:30
【问题描述】:

我有什么:

给定一棵描述系统如何由其通用部分组成的树(或更类似于有向图)。现在让这个系统成为例如人体及其身体部位的节点。

因此,例如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

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

【问题讨论】:

    标签: postgresql graph many-to-many common-table-expression recursive-query


    【解决方案1】:

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

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-02
      • 1970-01-01
      • 1970-01-01
      • 2020-07-25
      相关资源
      最近更新 更多