内部有连接的PostgreSQL递归CTE问题

内部有连接的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

我有一个带有两个表的PostgreSQL数据库,我需要使用它们进行递归查询。
这两个表如下所示:

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