SQL查找所有后代

时间:2015-01-29 20:41:02

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

我有一个像这样的数据表

 Entities:
 ID | Parent_ID
 1  | null
 2  | 1
 3  | 1
 4  | 3
 5  | 4
 6  | 4

我喜欢一个sql表达式,它会为每个实体和一个线性后代返回一行,如果实体没有后代,则为null返回一行。因此,鉴于上述数据,我的结果集将为:

Entity | Descendant
1      | 2
1      | 3
1      | 4
1      | 5
1      | 6
2      | null
3      | 4
3      | 5
3      | 6
4      | 5
5      | null
6      | null

我尝试使用常用的表格表达式来实现这一点,并认为它是这样做的方式,因为它具有递归的能力,但我无法绕过许多行的产生对于单亲。

with all_my_children (my_father,my_id,my_descendant,level)
as
(   
    select parent_id,id,null,0
    from Entities
    where id not in (select parent_id from entities)
    union all
    select e.parent_id,e.id,amc.my_id,amc.level+1 
    from Entities e
    inner join all_my_children amc 
    on e.id = amc.my_father
    WHERE ????? --How do I know when I'm done? and How do I keep repeating parents for each descendant?

)

select my_id, my_descendant from all_my_children

感谢您的时间。

2 个答案:

答案 0 :(得分:2)

删除了我以前的答案,但我认为这可能会解决问题......

WITH all_my_children AS (my_father,my_id,my_descendant,level)
        (
        SELECT  parent_id, id, null, 0
        FROM    Entities
        WHERE   parent_id IS NULL -- the roots of your tree
        UNION ALL
        SELECT  COALESCE(e2.parent_id, e.parent_id), e.id, amc.my_id, amc.level+1
        FROM    Entities e
        JOIN    all_my_children amc
        ON      e.parent_id = amc.my_id
        LEFT JOIN    Entities e2
        ON      e.id = e2.parent_id
        )
SELECT  * FROM  all_my_children

答案 1 :(得分:2)

这是你要求的

WITH TEMP AS
(

    SELECT ID AS ENTITY, PID AS DESCENDANTS
    FROM YPC_BI_TEMP.DBO.SV7104
    WHERE PID IS NULL
    UNION ALL
    SELECT PID AS ENTITY, ID AS DESCENDANTS
    FROM YPC_BI_TEMP.DBO.SV7104
    WHERE PID IS NOT NULL
    UNION ALL
    SELECT PRNT.ENTITY, CHILD.ID  AS DESCENDANTS
    FROM YPC_BI_TEMP.DBO.SV7104 AS CHILD
    INNER JOIN TEMP AS PRNT
    on PRNT.DESCENDANTS = CHILD.PID
    --AND PRNT.ENTITY IS NOT NULL

)
SELECT DISTINCT ENTITY, DESCENDANTS FROM TEMP
UNION
SELECT ID AS ENTITY, NULL AS DESCENDANTS FROM YPC_BI_TEMP.DBO.SV7104
WHERE ID NOT IN (SELECT ENTITY FROM TEMP)