SQL рекурсивный запрос для сложной таблицы - PullRequest
0 голосов
/ 05 ноября 2018

У меня довольно сложная структура таблицы с отношениями родитель-ребенок. Идея структуры заключается в том, что некоторый объект в child_id может вызвать parent_id. Предположим, эти данные;

Таблица 1 - карта

map_id | parent_id | child_id
1      | 1         | 2
2      | 1         | 3
3      | 1         | 4

Таблица 2 - атрибуты

attribute_id | child_id | id_to_trigger
1            | 2        | 5
2            | 5        | 6

Пример: система вопросников является мастером. Может содержать подгруппы для ответа; в этом случае подгруппы становятся дочерними по отношению к мастеру. Некоторые ответы в подгруппах могут вызвать дополнительную подгруппу в нем.

Теперь я хочу получить все идентификаторы подгрупп для данного мастера. Подгруппа может быть запущена из нескольких подгрупп, но это не проблема, поскольку мне нужны только идентификаторы подгруппы.

Как вы можете сказать, мастер с идентификатором 1 имеет 3 подгруппы 2, 3, 4. В таблице атрибутов мы видим, что подгруппа 2 может запускать подгруппу 5; аналогично 5 может вызвать 6 и т. д.

Мне нужно 2, 3, 4, 5, 6 в моем выводе. Как мне этого добиться?

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

Попробуйте это:

SELECT     
    map.parent_id, 
    map.child_id 
    FROM
    map 

    UNION

        SELECT     
        attributes.child_id, 
        attributes.id_to_trigger
        FROM
        map 
        Inner JOIN attributes ON map.child_id = attributes.child_id

    UNION

        SELECT  
        T1.child_id, 
        T1.id_to_trigger   
        FROM
        attributes T1 
        Inner JOIN attributes T2 ON T1.child_id = T2.id_to_trigger

Результат:

parent_id | child_id
1         | 2         
1         | 3         
1         | 4         
2         | 5         
5         | 6         
0 голосов
/ 05 ноября 2018

Подумайте о своем дизайне, я полагаю, что вам не нужны 2 таблицы, если вы добавите эти 2 записи в свою таблицу 1

map_id | parent_id | child_id
1      | 1         | 2
2      | 1         | 3
3      | 1         | 4
4      | 2         | 5
5      | 5         | 6

теперь вы можете использовать стандартную CTE для прогулки по дереву

как это

with Tree as (select child_id from table_1 where parent_id = 1
union all 
select table_1.child_id from table_1 
inner join Tree on Tree.child_id = table_1.parent_id)

select * from Tree

если вы не можете изменить схему, это будет работать

with 
table_1 as ( select Parent_id , child_id from map
                union all
                select child_id as Parent_id, id_to_trigger as child_id from attributes)
,Tree as (select child_id from table_1 where parent_id = 1
union all 
select table_1.child_id from table_1 
inner join Tree on Tree.child_id = table_1.parent_id)

select * from Tree
...