我在 Postresql 数据库中有两个具有多对多关系的表。
第一个主题表由三列组成。他们的名字是 id、name 和 parent。主题表具有层次结构:
id | 姓名 | 家长 |
---|---|---|
1 | 数学 | 0 |
2 | 代数 | 1 |
3 | 进步 | 2 |
4 | 数列 | 3 |
5 | 算术 | 1 |
6 | 总值 | 5 |
第二个表有名称任务表。它有两列 - 任务 ID 和任务文本:
id | 任务 |
---|---|
100 | 1+2+3+4 |
101 | 1+2 |
tasks_topics 表是
任务编号 | topics_id |
---|---|
100 | 3 |
100 | 6 |
101 | 1 |
我需要将表连接到主题的递归查询。它应该由四列组成。第一列应该是 task_id,第二列是任务文本,第三列应该是主题任务的父名称。最后一个应该是父主题 id。
结果应该是:
任务编号 | 姓名 | 主题名称 | topics_id |
---|---|---|---|
100 | 1+2+3+4 | 总值 | 6 |
100 | 1+2+3+4 | 算术 | 5 |
100 | 1+2+3+4 | 进步 | 3 |
100 | 1+2+3+4 | 代数 | 2 |
100 | 1+2+3+4 | 数学 | 1 |
101 | 1+2 | 数学 | 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加入任务。 我该如何解决这个问题?
首先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
_task_id = 100
topics_from = (
session.query(Tasks, Topics)
.join(Topics, Tasks.topics)
.filter(Tasks.id == _task_id) # optional
).cte(name="alltopic", recursive=True)
allq = topics_from.union(
session.query(Tasks, Topics)
.filter(Topics.id == topics_from.c.parent_id)
.filter(Tasks.id == topics_from.c.id)
)
应该产生如下结果:
(100, '1+2+3+4', 5, 'sum values', 3)
(100, '1+2+3+4', 6, 'Number sequences', 4)
(100, '1+2+3+4', 3, 'Arithmetics', 1)
(100, '1+2+3+4', 4, 'Progression', 2)
(100, '1+2+3+4', 1, 'Mathematics', 0)
(100, '1+2+3+4', 2, 'Algebra', 1)