我有一个PostgreSQL数据库,有两个表,我需要用它来做递归查询。
这两个表如下所示:PostgreSQL递归内部JOIN的CTE问题
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
...
主要表格,你可以看到可以为每个板块多种解决方案,每个管道多板,以及每盒多条管线。制作混合物表格以便使用几种溶液来制备1种溶液(例如使用66746和73002来制备75750)。
我需要做的是为每一行在Mixture表上做一个递归查询,以便返回到整个开始的整个历史记录。
如从主表的第一行:
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
然而,这没有奏效。这看起来像我的递归步骤不工作 - 查询会遍历主表中的所有行,但它只是返回主表和混合表之间JOIN的结果。
所以不是看上去就像上面的例子的结果,它看起来像这个:
Box pipeline plate made_solution_id used_solution_id
-----------------------------------------------------------------
X000001 Pipe 10000 75750 66746
X000001 Pipe 10000 75750 73002
我在做什么错?我阅读了递归查询文档,并在这里查看了递归CTE的几个问题,但我被卡住了。
编辑:改变的东西在SQL查询和小提琴的方式由欧文Brandstetter修改 http://www.sqlfiddle.com/#!11/9354f/4
PostgreSQL的8.4.17版本提供。
EDIT2:这是什么我的查询上的psql返回部分(注意:这只是一个例子,其中递归查询只是停止几个行后做递归事):
XYZ01 | High | 114043 | 49923 | 46573
XYZ01 | High | 115424 | 49923 | 46573
XYZ01 | High | 114043 | 46573 | 39853
XYZ01 | High | 115424 | 46573 | 39853
XYZ01 | High | 114043 | 46573 | 20456
XYZ01 | High | 115424 | 46573 | 20456
XYZ01 | High | 116694 | 49923 | 46573
XYZ01 | High | 116691 | 49923 | 46573
XYZ01 | High | 116697 | 49923 | 46573
XYZ01 | High | 116693 | 49923 | 46573
XYZ01 | High | 116696 | 49923 | 46573
XYZ01 | High | 116699 | 49923 | 46573
XYZ01 | High | 116698 | 49923 | 46573
XYZ01 | High | 116692 | 49923 | 46573
XYZ01 | High | 116695 | 49923 | 46573
其中。 ..不是什么小提琴返回。
我将使用递归cte遍历recursvie CTE中的混合表,然后将_that_的结果连接到主表。 –
@a_horse_with_no_name我想过要做到这一点 - 但这是事情 - 对于可能使用的几个解决方案(以及它们各自的父解决方案)用于在主表中为每行创建解决方案,我将如何跟踪Box ,管道等信息,如果我这样做?我需要知道那些父母属于哪个盒子,管道和盘子(注意他们也可以在几个盒子里)。我没有看到一种方法来通过递归cte在混合表上进行,然后再加入到主表中。 – Joe
我没有看到表格“盒子”(或任何适当的表格定义)的定义。另外:Postgres版本?理想情况下,你会为此提供一个SQL小提琴和一个测试用例。你可以在[这个存根]上建立(http://www.sqlfiddle.com/#!15/803b9)。 –