查找所有可以通过递归选择找到的条目

Finding all entries that can be found by recursive selection

我想select Countries that can be found by all countries in Countries that can be found by reducingly add all neighboring countries to the reachable countries already find by looking by looking by the set of just 'Sweden'.基本上,我的集合 S 最开始是集合 {Sweden},select 来自 table borders 的所有名称等于 Country1 属性,而 Country2 属性在S中,或者等于Country2属性,而Country1属性在S中。我将S修改为这个selected集合。然后我继续这样做 selection 直到我找不到不在 S 中的新国家。

通过在 table

上执行 selection
Country1      Country2
----------------------
Sweden        Finland
Norway        Sweden
Norway        Finland
Norway        Russia
Russia        Ukraine
Russia        Finland
Russia        China
Canada        United States

我应该得到结果:

Name
----------------------
Finland        
Norway        
Russia        
Ukraine       
China

这不是最好的,但我希望你明白我想做什么。我正在使用 PostgreSQL。

有点(已编辑)

create table borders(
    Country1 varchar(100),
    Country2 varchar(100)
);
insert into borders(Country1,Country2)
values
('Sweden','Finland'),
('Norway','Sweden'),
('Norway','Finland'),
('Norway','Russia'),
('Russia','Ukraine'),
('Russia','Finland'),
('Russia','China'),
('Canada','United States')
;

WITH RECURSIVE neighbours AS (
    -- start with 'Sweden' if any neighbour of it exists
    SELECT DISTINCT 'Sweden' as Name, ARRAY[cast('Sweden' as varchar)] as path
    FROM borders b 
    WHERE 'Sweden' IN (b.Country1, b.Country2)
    --
    UNION ALL
    SELECT 
      CASE WHEN nb.Name = b.Country1 THEN b.Country2 ELSE b.Country1 END, 
      path || CASE WHEN nb.Name = b.Country1 THEN b.Country2 ELSE b.Country1 END
    FROM borders b
    JOIN neighbours nb ON nb.Name IN(b.Country1, b.Country2) 
          AND NOT(b.Country1 = ANY(path) AND b.Country2 = ANY(path))
)
SELECT DISTINCT Name
FROM neighbours;