复杂表的SQL递归查询

时间:2018-11-05 10:34:03

标签: sql sql-server-2014 common-table-expression hierarchy

我有一个非常复杂的具有父子关系的表结构。 结构背后的想法是child_id中的某些对象可以触发parent_id。 假设这些数据;

表1-地图

<?php
$begin = (new DateTime())->setTime(0,0,0);  // create start point
$end = (new DateTime())->setTime(23,59,59); // create end point
$interval = new DateInterval('PT1M'); // set the interval to 1 minute
$daterange = new DatePeriod($begin, $interval ,$end);  // create the DatePeriod

echo "<select>";
foreach($daterange as $date){ // loop through that period
    echo "<option value='".$date->format("H:i") . "'>".$date->format("H:i")."</option>\n";
}
echo "</select>";

表2-属性

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

示例:调查表系统是一个主系统。它可以包含要回答的子组;在这种情况下,子组将成为主组的子组。子组中的某些答案可以触发其中的另一个子组。

我现在希望能够获取给定母版的所有子组ID。可以从多个子组触发一个子组,但这不是问题,因为我只需要子组ID。

您可以看到,标识为1的master具有3个子组2、3、4。在属性表中,我们可以看到子组2可以触发子组5;同样,5可以触发6,依此类推。

我的输出中需要2、3、4、5、6。我该如何实现?

2 个答案:

答案 0 :(得分:1)

考虑一下您的设计,如果将这两个记录添加到表1中,我建议您不需要2个表

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

答案 1 :(得分:1)

尝试一下:

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