内部有连接的PostgreSQL递归CTE问题
我有一个带有两个表的PostgreSQL数据库,我需要使用它们进行递归查询。内部有连接的PostgreSQL递归CTE问题,sql,postgresql,common-table-expression,recursive-query,Sql,Postgresql,Common Table Expression,Recursive Query,我有一个带有两个表的PostgreSQL数据库,我需要使用它们进行递归查询。 这两个表如下所示: Main table Box pipeline plate solution ---------------------------------------- X000001 Pipe 10000 75750 X000001 Pipe 10000 75751 X000001 Pipe 10001
这两个表如下所示:
Main table
Box pipeline plate solution
----------------------------------------
X000001 Pipe 10000 75750
X000001 Pipe 10000 75751
X000001 Pipe 10001 75752
X000001 Line 20000 75750
Y000002 Pipe 10007 75800
...
Mixture (Solution History)
made_solution_id used_solution_id
-------------------------------------
75750 66746
75750 73002
66746 76380
66746 80000
...
如您所见,主表中每个板可以有多个解决方案,每个管道可以有多个板,每个盒子可以有多个管道。制作混合表时,使用几种溶液制备一种溶液(例如,使用66746和73002制备75750)
我需要做的是对每一行对混合表进行递归查询,以便返回到开始的整个历史记录
例如,对于主表的第一行:
Box pipeline plate made_solution_id used_solution_id
-----------------------------------------------------------------
X000001 Pipe 10000 75750 66746
X000001 Pipe 10000 75750 73002
X000001 Pipe 10000 66746 76380
X000001 Pipe 10000 66746 80000
(一直递归,直到没有用于生成解决方案的父解决方案)
... 对主表中的所有行执行此操作
为此,我提出了一个递归查询:
WITH RECURSIVE parents (box, pipeline, plate, made_solution_id, used_solution_id)
AS (
--get leaf solution
SELECT
box, pipeline, plate, made_solution_id, used_solution_id
FROM
main
JOIN
mixture
ON
solution = made_solution_id
UNION
--get parent solutions
SELECT
t.box, t.pipeline, t.plate, m.made_solution_id, m.used_solution_id
FROM
main t
JOIN
parents pt
ON
pt.made_solution_id = t.solution
JOIN
mixture m
ON
pt.used_solution_id = m.made_solution_id
)
SELECT * from parents
然而,这并没有起作用。似乎我的递归步骤不起作用了——查询确实遍历了主表中的所有行,但它只返回主表和混合表之间的联接结果
因此,与上面的示例结果不同,它是这样的:
Box pipeline plate made_solution_id used_solution_id
-----------------------------------------------------------------
X000001 Pipe 10000 75750 66746
X000001 Pipe 10000 75750 73002
我做错了什么?我阅读了递归查询文档,也看了关于递归CTE的几个问题,但是我被卡住了
编辑:更改了Erwin Brandstetter提供的SQL查询和fiddle中的某些内容
顺便说一下,PostgreSQL版本8.4.17
EDIT2:这是我的查询在psql上返回的内容的一部分(注意:这只是一个示例,其中递归查询在几行之后停止执行递归操作):
哪个。。。这不是提琴返回的东西。您需要返回CTE第二部分中的盒子、管道、m板,而不是t板。否则,您将浏览解决方案,是的,但不会显示其余内容的当前内容(这似乎是您想要的)。您将只显示第一个
WITH RECURSIVE parents (box, pipeline, plate, made_solution_id, used_solution_id)
AS (
--get leaf solution
SELECT
box, pipeline, plate, made_solution_id, used_solution_id
FROM
main
JOIN
mixture
ON
solution = made_solution_id
UNION
--get parent solutions
SELECT
m.box, m.pipeline, m.plate, m.made_solution_id, m.used_solution_id
FROM
main t
JOIN
parents pt
ON
pt.made_solution_id = t.solution
JOIN
mixture m
ON
pt.used_solution_id = m.made_solution_id
)
SELECT * from parents
我将使用递归cte只遍历递归cte中的混合表,然后将其结果连接到主表。@a_horse_,带有_no_名称,我想这样做-但这里有一件事-对于可能使用的几个解决方案(以及它们各自的父级使用的解决方案),用于在主表中生成每行的解决方案,如果我这样做,我将如何跟踪箱子、管道等信息?我需要知道这些父母将属于哪个盒子、管道和盘子(注意,他们也可能在几个盒子里)。我不认为只有在混合表上递归cte并随后连接到main才能做到这一点。我看不到table
box
的定义(或任何适当的表定义)。还有:博士后版?理想情况下,您应该提供一个带有测试用例的SQL FIDLE。您可以建立在。@ErwinBrandstetter啊,对不起-不知道什么是SQL Fiddle!谢谢我在作品中加入了一些东西之后又加入了小提琴。还有一些奇怪的东西。小提琴返回的行数似乎比我在命令行上使用相同查询得到的行数还要多-_-当我在psql上运行它时,我在帖子中更清楚地说明了发生了什么。再次感谢你的小提琴演奏棒。
WITH RECURSIVE parents (box, pipeline, plate, made_solution_id, used_solution_id)
AS (
--get leaf solution
SELECT
box, pipeline, plate, made_solution_id, used_solution_id
FROM
main
JOIN
mixture
ON
solution = made_solution_id
UNION
--get parent solutions
SELECT
m.box, m.pipeline, m.plate, m.made_solution_id, m.used_solution_id
FROM
main t
JOIN
parents pt
ON
pt.made_solution_id = t.solution
JOIN
mixture m
ON
pt.used_solution_id = m.made_solution_id
)
SELECT * from parents