在sql中获取直接层次结构,而不包含搜索id的同级

4dbbbstv  于 2021-08-09  发布在  Java
关注(0)|答案(1)|浏览(348)

我有一个非常简单的表,名为types,它包含id、parentid和name。我需要的是从一个id得到完整的层次结构,但不包括搜索id的同级,

;WITH cte AS ( 
   SELECT ID, ParentID, [Name]
   FROM   [Types]
   WHERE  ID=246
   UNION ALL 
   SELECT t1.ID, t1.ParentID, t1.[Name]
   FROM   [Types] t1 
   INNER JOIN cte ON cte.ID=t1.ParentID 
    ) 
SELECT * FROM cte

它给出了表的完整层次结构(最上面的父级是id“246”):

到目前为止,还不错。我现在想从查询中得到的是id:1384的完整层次结构,但是没有id 1384的兄弟姐妹(以及兄弟姐妹的子女、孙子等)。因此它应该返回以下结果:

+------+----------+------------------+
| ID   | ParentID | Name             |
+------+----------+------------------+
| 246  | 2        | Approvals        |
+------+----------+------------------+
| 1384 | 246      | ProductStatus    |
+------+----------+------------------+
| 1517 | 1384     | NewStatus        |
+------+----------+------------------+
| 1520 | 1384     | NewSiblingStatus |
+------+----------+------------------+
| 1519 | 1517     | NewNewStatus     |
+------+----------+------------------+

我读过关于检索层次结构的各种文章,但到目前为止还没有找到解决这个问题的方法,也没有找到有类似问题的人。

cnh2zyt3

cnh2zyt31#

一种方法是使用两个递归公共表表达式。一个去找父母,另一个去找孩子。那你就可以了 union 让他们得到你想要的结果- union (而不是 union all )是为了消除初始节点上的重复。

WITH 
    cte_children AS ( 
       SELECT ID, ParentID, [Name], 0 lvl
       FROM [Types]
       WHERE ID = 1384
       UNION ALL 
       SELECT t.ID, t.ParentID, t.[Name], lvl - 1
       FROM [Types] t
       INNER JOIN cte_children c ON c.ID = t.ParentID 
    ) 
    cte_parents AS ( 
       SELECT ID, ParentID, [Name], 0 lvl
       FROM [Types]
       WHERE  ID = 1384
       UNION ALL 
       SELECT t.ID, t.ParentID, t.[Name], lvl + 1
       FROM [Types] t
       INNER JOIN cte ON cte.ParentID = t.ID 
    ) 
SELECT * FROM cte_parents
UNION
SELECT * FROM cte_children  
ORDER BY lvl

注意,我添加了一个名为 lvl 对于查询,它计算每个节点的深度(初始注解 0 ,父母有负面影响 lvl s、 孩子们有积极的 lvl s) -这便于对最终结果集进行排序。

相关问题