2017-01-16 2 views
0

У меня есть таблица структурированаPostgreSQL perent со списком ребенка

Id int(10) 
ROOT_ID int(10) --reference I'd 
Name 

Эта таблица содержит структуру parants и сыновей. Пример данные

Id | parent | name 
1  Null  A 
2  1  B 
3  1  C 
4  Null  D 
5  4  E 
6  5  F 

Пример содержит простой пример наследия я хотел бы найти с помощью PostgreSQL всего родительского происхождения со списком ребенка

что-то вроде

Id | name | all Childs 
1  A  B,C 
4  D  E,F 

Могу ли я сделать это через PostgreSQL? Или я должен работать через Java рекурсию после трогания строки

+2

«Все ли дети» представляют все _descendants_ на любой глубине? Если нет, то почему 'F' указан как ребенок' D'? –

+0

Да, мне нужны все потомки – YSherf

ответ

0

Для того, чтобы найти все дочерние записи, нужно использовать рекурсивный запрос:

WITH RECURSIVE t(root_parent, id, parent, name) AS (
    SELECT id as root_parent, id, parent, name FROM your_table WHERE parent IS NULL 
    UNION ALL 
    SELECT t.root_parent, your_table.id, your_table.parent, your_table.name FROM your_table, t WHERE your_table.parent = t.id 
) 
SELECT t.root_parent as id, your_table.name, array_agg(t.name) as children 
FROM t 
JOIN your_table ON your_table.id = t.root_parent 
WHERE t.parent IS NOT NULL 
GROUP BY t.root_parent, your_table.name 
ORDER BY t.root_parent 

Демо: http://rextester.com/AEA93879

Вы можете прочитать о рекурсивном запросы в PostgreSQL documentaion


выше запросы могут показаться слишком запутанными первым, позвольте мне объясните это немного. Он состоит из двух частей: самого рекурсивного запроса и select-query. Вот вывод рекурсивного запроса:

WITH RECURSIVE t(root_parent, id, parent, name) AS (
    SELECT id as root_parent, id, parent, name FROM your_table WHERE parent IS NULL 
    UNION ALL 
    SELECT t.root_parent, your_table.id, your_table.parent, your_table.name FROM your_table, t WHERE your_table.parent = t.id 
) 
SELECT * FROM t 

----------------------------------- 
| root_parent | id | parent | name | 
|1   |1 |  |"A" | 
|4   |4 |  |"D" | 
|1   |2 |1  |"B" | 
|1   |3 |1  |"C" | 
|4   |5 |4  |"E" | 
|4   |6 |5  |"F" | 
------------------------------------ 

И вторая часть запроса просто выполняет группировку, так что список детей показан для каждой корневой записи.