最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

postgresql - Converting SQL Server CTE with multiple recursive members to Postgres throws error as multiple recursive members ar

programmeradmin2浏览0评论

The SQL below gets ancestors in SQL Server using multiple recursive members, copied from an article by Itzik Ben-Gan in ITProToday back in 2013;

DROP TABLE IF EXISTS tmp_FamilyTree;
CREATE temporary TABLE tmp_FamilyTree
(
    id INT NOT NULL CONSTRAINT PK_FamilyTree PRIMARY KEY,
    name VARCHAR(30) NOT NULL,
    mother INT NULL,
    father INT NULL
);
INSERT INTO tmp_FamilyTree
(
    id,
    name,
    mother,
    father
)
VALUES
(   1,
    'Balbo Baggins',
    NULL,
    NULL),
(   2,
    'Berylla Boffin',
    NULL,
    NULL),
(   3,
    'Mungo Baggins',
    1,
    2),
(   4,
    'Laura Grubb',
    NULL,
    NULL),
(   5,
    'Bungo Baggins',
    3,
    4),
(   6,
    'Belladonna Took',
    NULL,
    NULL),
(   7,
    'Bilbo Baggins',
    5,
    6),
(   8,
    'Largo Baggins',
    1,
    2),
(   9,
    'Tanta Hornblower',
    NULL,
    NULL),
(   10,
    'Fosco Baggins',
    8,
    9),
(   11,
    'Ruby Bolger',
    NULL,
    NULL),
(   12,
    'Dora Baggins',
    10,
    11),
(   13,
    'Drogo Baggins',
    10,
    11),
(   14,
    'Dudo Baggins',
    10,
    11),
(   15,
    'Primula Brandybuck',
    NULL,
    NULL),
(   16,
    'Frodo Baggins',
    13,
    15);

WITH recursive C
AS ( -- anchor queries  
      -- father of input  
    SELECT father AS id,
             1 AS lvl
    FROM tmp_FamilyTree
    WHERE id = 16
    AND father IS NOT NULL
    UNION ALL -- mother of input  
    SELECT mother AS id,
             1 AS lvl
    FROM tmp_FamilyTree
    WHERE id = 16
    AND mother IS NOT NULL
    UNION ALL -- recursive queries  
                 -- fathers of those in previous level  
    SELECT father AS id,
             C.lvl + 1 AS lvl
    FROM C
    JOIN tmp_FamilyTree AS P ON C.id = P.id
    WHERE P.father IS NOT NULL
    UNION ALL -- fathers of those in previous level  
    SELECT mother AS id,
             C.lvl + 1 AS lvl
    FROM C
    JOIN tmp_FamilyTree AS P ON C.id = P.id
    WHERE P.mother IS NOT NULL)
SELECT C.id,
         FT.name,
         lvl
FROM C
JOIN tmp_FamilyTree AS FT ON C.id = FT.id;

When run in Postgres this throws error 'recursive reference to query "c" must not appear within its non-recursive term'. Running it in SQL Server, removing keywords recursive and Temporary, returns 8 rows. How can this be fixed in Postgres to also return 8 rows?

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论