【问题标题】:join table to recursive query of other table in potresql将表连接到potresql中其他表的递归查询
【发布时间】:2023-02-25 05:11:31
【问题描述】:

我在 Postgresql 数据库中有两个具有多对多关系的表。

第一个主题表由三列组成。他们的名字是 id、name 和 parent。主题表具有层次结构:

id name parent
1 Mathematics 0
2 Algebra 1
3 Progression 2
4 Number sequences 3
5 Arithmetics 1
6 sum values 5

第二个表有名称任务表。它有两列 - 任务 ID 和任务文本:

id task
100 1+2+3+4
101 1+2

tasks_topics 表是

task_id topics_id
100 3
100 6
101 1

我需要将表连接到主题的递归查询。它应该由四列组成。第一列应该是 task_id,第二列是任务文本,第三列应该是主题任务的父名称。最后一个应该是父主题 ID。

结果应该是:

task_id name topics_name topics_id
100 1+2+3+4 sum values 6
100 1+2+3+4 Arithmetics 5
100 1+2+3+4 Progression 3
100 1+2+3+4 Algebra 2
100 1+2+3+4 Mathematics 1
101 1+2 Mathematics 1

我可以对主题表进行递归查询

WITH RECURSIVE topic_parent AS (
  SELECT 
    id, 
    name, 
    parent 
  FROM 
    topics 
  WHERE 
    id = 3 
  UNION 
  SELECT 
    topics.id, 
    topics.name, 
    topics.parent 
  FROM 
    topics 
    INNER JOIN topic_parent ON topic_parent.parent = topics.id
) 
SELECT 
  * 
FROM 
  topic_parent

;

但我不知道如何通过 id 将其加入任务。 我应该如何解决这个问题?

【问题讨论】:

    标签: sql postgresql recursion many-to-many common-table-expression


    【解决方案1】:

    首先cte (WITH RECURSIVE) 是获取主题的父母, cte2 将主题数组转换为行, 然后我们将数据连接在一起以获得预期的结果。

      WITH RECURSIVE topic_parent(id, path) AS (
      SELECT 
        id, ARRAY[id]
      FROM topics 
      WHERE parent = 0
      UNION 
      SELECT 
        t.id, path || t.id
      FROM 
        topics t
        INNER JOIN topic_parent rt ON rt.id = t.parent
    ),
    cte2 as (
      select *, unnest(path) AS linked_id
      from topic_parent
    )
    select task_id, max(task) as task_name, max(name) as topic_name, linked_id as topic_id
    from cte2 c
    inner join tasks_topics t on c.id = t.topics_id
    inner join tasks t2 on t2.id = t.task_id
    inner join topics t3 on t3.id = c.linked_id
    group by task_id, linked_id
    order by task_id asc, linked_id desc
    

    Demo here

    【讨论】:

    • 非常感谢。当我在父级为 0 的主题表中插入值时,此查询效果不佳。例如dbfiddle.uk/xSHgs8xI
    • 当父 0 有多个主题时,我已经包含了这个用例
    猜你喜欢
    • 2010-09-12
    • 2018-09-26
    • 2018-01-03
    • 2021-10-03
    • 1970-01-01
    • 2015-05-05
    • 1970-01-01
    • 1970-01-01
    • 2018-09-01
    相关资源
    最近更新 更多