英文:
join table to recursive query of other table in potresql
问题
我有两个表在PostgreSQL数据库中,它们之间有多对多的关系。
第一个表是Topic表,包含三列,它们的名称分别是id、name和parent。Topic表具有层次结构:
id | name | parent |
---|---|---|
1 | Mathematics | 0 |
2 | Algebra | 1 |
3 | Progression | 2 |
4 | Number sequences | 3 |
5 | Arithmetics | 1 |
6 | sum values | 5 |
第二个表名为task表,它包含两列 - task id和task text:
id | task |
---|---|
100 | 1+2+3+4 |
101 | 1+2 |
tasks_topics表如下:
task_id | topics_id |
---|---|
100 | 3 |
100 | 6 |
101 | 1 |
我需要将这两个表与Topic的递归查询联接起来。结果表应包含四列。第一列应该是task_id,第二列是task text,第三列是topic任务的所有父级名称,最后一列是父级topic的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 |
我可以使用以下递归查询来获取Topic表的层次结构:
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;
但我不知道如何将它与task表通过id联接起来。你应该如何解决这个问题?
英文:
I have two tables with many to many relationship in Postresql database.
The first Topic table consists of three columns. Their names are id, name and parent. Topic table has hierarchial structure:
id | name | parent |
---|---|---|
1 | Mathematics | 0 |
2 | Algebra | 1 |
3 | Progression | 2 |
4 | Number sequences | 3 |
5 | Arithmetics | 1 |
6 | sum values | 5 |
The second table has name task table. It has two columns - task id and task text:
id | task |
---|---|
100 | 1+2+3+4 |
101 | 1+2 |
tasks_topics table is
task_id | topics_id |
---|---|
100 | 3 |
100 | 6 |
101 | 1 |
I need to get the table jointed to recursive query of topic. It should consists of four columns. THe first column should be task_id, the second task text, the third should be al parent names of topic tasks. And the last one should be parent topic id.
The result should be:
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 |
I can make recursive query to topic table
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
;
but I don't know ho to join it to task by id.
How should I solve this problem?
答案1
得分: 1
第一个公共表达式(WITH RECURSIVE
)用于获取主题的父级,cte2
用于将主题数组转换为行,然后我们将数据连接在一起以获得预期的结果。
英文:
First cte (WITH RECURSIVE
) is to get topics parents,
cte2
to convert the array of topics to rows,
Then we join data together to get the expected result.
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
答案2
得分: 0
以下是翻译好的代码部分:
_task_id = 100
topics_from = (
session.query(Tasks, Topics)
.join(Topics, Tasks.topics)
.filter(Tasks.id == _task_id) # optional
).cte(name="alltopic", recursive=True)
# union or union_all depending on if you want to filter out duplicates (top level)
allq = topics_from.union(
session.query(Tasks, Topics)
.filter(Topics.id == topics_from.c.parent_id)
.filter(Tasks.id == topics_from.c.id)
)
WITH RECURSIVE alltopic(id, task, id_1, name, parent_id) AS
(SELECT tasks.id AS id,
tasks.task AS task,
topics.id AS id_1,
topics.name AS name,
topics.parent_id AS parent_id
FROM tasks
JOIN tasks_topics AS tasks_topics_1 ON tasks.id = tasks_topics_1.task_id
JOIN topics ON topics.id = tasks_topics_1.topics_id
topics.parent_id AS topics_parent_id
FROM tasks,
topics,
alltopic
WHERE topics.id = alltopic.parent_id
AND tasks.id = alltopic.id)
SELECT alltopic.id,
alltopic.task,
alltopic.id_1,
alltopic.name,
alltopic.parent_id
FROM alltopic
英文:
_task_id = 100
topics_from = (
session.query(Tasks, Topics)
.join(Topics, Tasks.topics)
.filter(Tasks.id == _task_id) # optional
).cte(name="alltopic", recursive=True)
# union or union_all depending on if you want to filter out duplicates (top level)
allq = topics_from.union(
session.query(Tasks, Topics)
.filter(Topics.id == topics_from.c.parent_id)
.filter(Tasks.id == topics_from.c.id)
)
should produce result as per below:
(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)
via SQL along these lines:
WITH RECURSIVE alltopic(id, task, id_1, name, parent_id) AS
(SELECT tasks.id AS id,
tasks.task AS task,
topics.id AS id_1,
topics.name AS name,
topics.parent_id AS parent_id
FROM tasks
JOIN tasks_topics AS tasks_topics_1 ON tasks.id = tasks_topics_1.task_id
JOIN topics ON topics.id = tasks_topics_1.topics_id
topics.parent_id AS topics_parent_id
FROM tasks,
topics,
alltopic
WHERE topics.id = alltopic.parent_id
AND tasks.id = alltopic.id)
SELECT alltopic.id,
alltopic.task,
alltopic.id_1,
alltopic.name,
alltopic.parent_id
FROM alltopic
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论