PostgreSQL рекурсивный с - PullRequest
       6

PostgreSQL рекурсивный с

12 голосов
/ 22 июля 2010

Мне нужна помощь с рекурсивным запросом. Предполагая следующую таблицу:

CREATE TEMPORARY TABLE tree (
    id        integer PRIMARY KEY,
    parent_id integer NOT NULL,
    name      varchar(50)
);    

INSERT INTO tree (id, parent_id, name) VALUES (3, 0, 'Peter'), (2,0, 'Thomas'), (5,2, 'David'), (1, 0, 'Rob'), (8, 0, 'Brian');

Я могу получить список всех людей и их детей по следующему запросу:

WITH RECURSIVE recursetree(id, parent_id) AS (
    SELECT id, parent_id FROM tree WHERE parent_id = 0
  UNION
    SELECT t.id, t.parent_id
    FROM tree t
    JOIN recursetree rt ON rt.id = t.parent_id
  )
SELECT * FROM recursetree;

Как я могу перечислить их по порядку, а также отсортировать элементы первого уровня по имени? Например, желаемый результат будет:

id, parent_id, name    
8, 0, "Brian"
3, 0, "Peter"
1, 0; "Rob"
2, 0, "Thomas"
5, 2, "  David"

Спасибо

** EDIT. Обратите внимание, что добавление ORDER BY не будет работать: **

WITH RECURSIVE recursetree(id, parent_id, path, name) AS (
    SELECT 
        id, 
        parent_id, 
        array[id] AS path, 
        name 
    FROM tree WHERE parent_id = 0
  UNION ALL
    SELECT t.id, t.parent_id, rt.path || t.id, t.name
    FROM tree t
    JOIN recursetree rt ON rt.id = t.parent_id
  )
SELECT * FROM recursetree ORDER BY path;

Вышесказанное сохранит отношения родитель-потомок (дети следуют за родителями), но применение любого другого предложения ORDER BY (т. Е. Name - как предлагали некоторые) приведет к тому, что результат потеряет свои отношения родитель-потомок.

1 Ответ

7 голосов
/ 22 июля 2010

См. Также эту (переведенную) статью о CTE в PostgreSQL: wiki.phpfreakz.nl

Редактировать: Попробуйте это, используя массив:

WITH RECURSIVE recursetree(id, parent_ids, firstname) AS (
    SELECT id, NULL::int[] || parent_id, name FROM tree WHERE parent_id = 0
  UNION ALL
    SELECT 
    t.id, 
    rt.parent_ids || t.parent_id, 
    name
    FROM tree t
    JOIN recursetree rt ON rt.id = t.parent_id
  )
SELECT * FROM recursetree ORDER BY parent_ids;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...