2014-02-10 52 views
2

我在这里看过一些递归查询,但没有找到我的问题。除此之外,我是PostgreSQL的新手。postgreSQL中的递归查询?

我有一个示例数据如下表:

number numberto ab st kz pv 
112  200     
140  210     
200  210     
210  220   f2 140 H 2011 
220     f2 140 H 2011  

查询将是一个比较复杂一点,但是这是我解决不了的部分。 numberto指的是另一个number然后可能再次。我可以说这个链条会持续四五次。

有一天,其他四个coloumns然后是NOT NULL和充满字母和/或数字。如果ab有内容,那么其他三个也会有。如果最后一个彩色色块被填满,numberto可以进一步提及,但将保持不变,所以它能够在那里停止。

我的问题:我需要做一个数字的递归查询,然后根据需要搜索numberto多少次,直到例如然后填充ab并获得它们的输出。

我该如何做到这一点?


SELECT version(); 

在x86_64未知-Linux的GNU的PostgreSQL 9.2.6,与gcc编译(SUSE Linux)的4.3.4 [GCC-4_3-分支修订152973],64位

+1

请显示一个有用的数据示例,至少足以显示一个完整的案例(输入和预期输出)。请给你的PostgreSQL版本。 –

+0

我试图添加示例数据并添加版本();输出。请告诉我,如果我能改善这个答案。 :) – Trollwut

+1

好吧,所以你想要走上numberto - >数字链,直到找到非空数据列。正确? –

回答

2

这是一个非常简单的递归查询,当您在递归术语中看到一个非空行时,您就会停止。

鉴于the following sample table

WITH RECURSIVE chain AS 
(
    -- Start with the row with number=140 
    SELECT number, numberto, ab, st, kz, pv 
    FROM numbers n 
    WHERE n.number = 140 
    UNION ALL 
    -- and iteratively fetch the 'numberto' id'd row 
    SELECT n.number, n.numberto, n.ab, n.st, n.kz, n.pv 
    FROM chain c 
    INNER JOIN numbers n ON (c.numberto = n.number) 
    -- unless we've already found a non-null col in our last iteration 
    WHERE c.ab IS NULL 
) 
-- Find any non-null result. 
SELECT * 
FROM chain c 
WHERE c.ab IS NOT NULL; 

应该做的伎俩,其中n.number = 140是你的启动条件。

如果您发现非空col,或者如果您有一个NULL numberto或不匹配的numberto(因为内部联接将不添加行),则迭代停止。

+0

我现在试了几个小时......你确定你可以在第二个SELECT中引用“n”吗?因为我的SQL程序只接受“c”。那里作为参考... – Trollwut

+0

@Trollwut绝对确定;遵循SQLFiddle链接,该链接演示了它按照书面形式运行。在这里重复:http://sqlfiddle.com/#!15/41a9e/3 –

+0

Yessir,也适用于我的postgreSQL版本。但是我遇到了一个问题,其中一行实际上是LEFT JOINed ...然后我没有得到它的工作。尽管如此,你的回答是对的 - 明天我会为此工作。 – Trollwut