首页 > 解决方案 > 递归查找所有级别的孩子

问题描述

我有 2 张桌子。在这里提琴

Details

+-----+-----------+
| id  | valid     |
+-----+-----------+
| 101 | VALID     |
| 102 | NOT VALID |
| 103 | VALID     |
| 104 | NOT VALID |
+-----+-----------+

Relation

+---------+----------+-------+  
| parent  | child    | stock |
+---------+----------+-------+
| 101     | 101A     | 3     |
| 101     | 101B     | 1     |
| 101     | 101C     | 4     |
| 101A    | 101A-V1  | 3     |
| 101A-V1 | 101A-V2  | 6     |
| 102     | 102A     | 2     |
| 102     | 102B     | 3     |
| 103     | 103A     | 5     |
| 103     | 103BB    | 4     |
| 103     | 103M     | 5     |
| 103BB   | 103BB-V1 | 4     |
+---------+----------+-------+

我必须从表中获取带有“VALID”的 id,并从表中Details找到其所有级别的子级。relation所以预期的输出是

+----------+-------+
| ID       | Valid |
+----------+-------+
| 101      | VALID |
| 101A     | VALID |
| 101B     | VALID |
| 101C     | VALID |
| 101A-V1  | VALID |
| 101A-V2  | VALID |
| 103      | VALID |
| 103A     | VALID |
| 103BB    | VALID |
| 103M     | VALID |
| 103BB-V1 | VALID |
+----------+-------+

我已经尝试了下面的 cte,但它没有给它的孩子。我只得到最高的父母。

;with Cte2 As
        (
        SELECT a.*
        FROM details a
        WHERE a.valid = 'VALID'
        
        UNION ALL
        
        SELECT a.*
        FROM details a
        join relation s 
        on a.id = s.child
        JOIN cte2 c ON s.parent = c.id
        )
        select * FROM Cte2 

在这里提琴

标签: sql-serversql-server-2012

解决方案


由于子 ID 不存在于明细表中,加入不会提取任何内容。

我认为你应该这样做。

;with cte2 as
        (
        select 
            a.id,
            a.valid
        from details a
        where a.valid = 'VALID'
        union all
        select 
            s.child,
            c.valid
        from relation s 
        join cte2 c on s.parent = c.id
        )

select * from cte2 
order by cte2.id

推荐阅读