2014-02-18 70 views
0

我在我的数据库中有以下关系;大递归SQL查询

Column |   Type   | Modifiers 
----------+----------------------+----------- 
country1 | character varying(4) | not null 
country2 | character varying(4) | not null 
length | numeric    | 

带有示例数据

country1 | country2 | length 
----------+----------+-------- 
AL  | GR  | 282 
AL  | MK  | 151 
AL  | MNE  | 172 
AL  | KOS  | 112 

,我想在那里我找到了所有可从陆路法国所能够到达的国家写一个递归查询。我会如何去做这件事?

我想出了这个至今:

WITH Recursive frborders(country) AS 
(
SELECT country1 FROM borders WHERE country2 = 'FR' 
) 

SELECT name FROM frborders; 

但我没有得到期望的结果,我怎么会去这样做?我正在使用PostgreSQL。

+0

你应该指定你正在使用的数据库。 –

+0

我使用PostgreSQL,但不想使用限制它的语法。 – Stabbah

+0

仅供参考,如果您使用的是PostgreSQL,那么您只能使用PostgreSQL中有效的语法。 – valverij

回答

0

你这样做的方式(至少在你要去的方向)在不同的平台上会有所不同。在PostgreSQL中,您需要实际调用您的语句,因此:

WITH RECURSIVE frborders (country1, path) AS (
    SELECT country1, ARRAY['FR']::varchar[] AS "array" 
    FROM borders 
    WHERE country2 = 'FR' 
    UNION ALL 
    SELECT borders.country1, borders.country2||path 
    FROM frborders, borders 
    WHERE borders.country2 = frborders.country1 
) 
select * from frborders; 

做了类似我想象的事情。我添加了一条路径让我更清楚。

SQL Server上的语法类似但不同,并且没有数组,因此路径将不起作用(但您不希望这样做)。在MySQL上,你可以使用临时表和存储过程来做到这一点,但它看起来不像这样。有一个独立于平台的方法可以做到这一点,但它需要一个非常不同的表结构。另外,您至少需要一个'FR'边框条目。

+0

递归公用表表达式*是独立于平台的方式。尽管语法略有不同,但是所有现代数据库管理系统都支持这种* *(除了MySQL--它几乎不是“现代”的) –