2010-09-14 2 views
7

У меня есть таблица ведьму содержит поля: ID, parent_id, имя (и т.д.)Выберите строки из таблицы, используя заказ дерева

я хочу заказать эту таблицу в «дереве порядка перемещения», то есть.

id parent_id 
1, 0 
3, 1 
5, 1 

2, 0 
8, 2 

4, 0 
9, 4 

(...)

короче описать: взять корневой узел, добавьте все дети, возьмите следующий корневой узел добавить детей и т.д.

ответ

10

По Вашему описанию я предполагаю, вы имеете в виду breadth- первого порядка, что может быть сделано Исли с помощью рекурсивных запросов (PostgreSQL 8.4+):

WITH RECURSIVE tree 
AS 
(
    SELECT 
     node_name, id, parent_id, NULL::varchar AS parent_name 
    FROM foo 
    WHERE parent_id IS NULL 
    UNION 
    SELECT 
     node_name, f1.id, f1.parent_id, tree.node_name AS parent_name 
    FROM 
     tree 
     JOIN foo f1 ON f1.parent_id = tree.id 
) 
SELECT node_name, empno, parent_id, node_name FROM tree; 

Вы также можете использовать глубину первого порядка с использованием следующих SQL:

WITH RECURSIVE tree 
AS 
(
    SELECT 
     node_name, id, parent_id, NULL::varchar AS parent_name, id::text AS path 
    FROM foo WHERE parent_id IS NULL 
    UNION 
    SELECT 
     node_name, f1.id, f1.parent_id, tree.node_name AS parent_name, tree.path || '-' || f1.id::text AS path 
    FROM 
     tree 
     JOIN foo f1 ON f1.parent_id = tree.id 
) 
SELECT node_name, empno, parent_id, node_name, path FROM tree ORDER BY path; 
+0

Thx для этого я не знал о существующих запросах WITH в Postgres – canni

+0

Я думаю, что мы не можем использовать оператор UNION в разделе WITH – Fer

+1

Ваше решение для порядок глубин не будет работать для id с разным количеством цифр. – synergetic

-2
SELECT * FROM table ORDER BY id,parent_id 

Это должен заказать мои столбцы в порядок, размещенный в запросе.

Если вы имеете в виду группирует элементы, ведьма я думаю, что вы делаете, а затем использовать

SELECT * FROM table ORDER BY id GROUP BY parent_id 

И я также советую вам прочитать эту статью: http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

+0

Это не даст результатов, чтобы я хочу ... – canni

+0

Это будет производить синтаксическую ошибку в Postgres (поле идентификатора должно быть использовано в совокупной функции), это не MySQL :) – canni

+0

Ahh ok, извините, я думал, что это сработало бы под 'postgres', im не так хорошо с ним. – RobertPitt

0

Вы также можете использовать отличный LTree модуль, но вам необходимо реорганизовать данные немного.

4

Как отмечает синергетического, решение по глубине первого порядка обеспечивается Диог Biazus не будет работать для идентификаторов с разным количеством цифр.

Но вы можете использовать это решение вместо этого, который использует массивы целого:

WITH RECURSIVE tree 
AS 
(
    SELECT 
     node_name, id, parent_id, NULL::varchar AS parent_name, array[id] AS path 
    FROM foo WHERE parent_id IS NULL 
    UNION 
    SELECT 
     node_name, f1.id, f1.parent_id, tree.node_name AS parent_name, tree.path || f1.id AS path 
    FROM 
     tree 
     JOIN foo f1 ON f1.parent_id = tree.id 
) 
SELECT node_name, empno, parent_id, node_name, path FROM tree ORDER BY path; 
Смежные вопросы