【问题标题】:How to get all children of a parent and then their children using recursion in query如何在查询中使用递归获取父母的所有孩子,然后是他们的孩子
【发布时间】:2018-07-06 10:13:39
【问题描述】:

我有这样的结构:

<Unit>
  <SubUnit1>
           <SubSubUnit1/>
           <SubSubUnit2/>
           ...
           <SubSubUnitN/>
  </SubUnit1/>
  <SubUnit2>
           <SubSubUnit1/>
           <SubSubUnit2/>
           ...
           <SubSubUnitN/>
  </SubUnit2/>
  ...
  <SubUnitN>
           <SubSubUnit1/>
           <SubSubUnit2/>
           ...
           <SubSubUnitN/>
  </SubUnitN/>
</Unit>

这个结构有3个层次:主单元、子单元和子子单元。

我想按 UnitId 选择所有孩子。
如果我按单位搜索,我必须得到所有的树。
如果我按 SubUnit1 搜索,我必须得到 SubUnit1 和 SubUnit1 的所有子项。
如果我搜索 SubSubUnit2,我必须得到它自己。

这是我的尝试:

with a(id, parentid, name)
as (
select id, parentId, name
   from customer a
   where parentId is null 
union all
   select a.id, a.parentid, a.Name
   from customer
     inner join a on customer.parentId = customer.id
    )
select parentid, id, name 
from customer pod
where pod.parentid in (
select id
from customer grbs
where grbs.parentid in (
select id
from customer t
where t.parentid = @UnitId
))
union 
select parentid, id, name
from customer grbs
where grbs.parentid in (
select id
from customer t
where t.parentid = @UnitId
)
union
select parentid, id, name
from customer c
where c.Id = @UnitId
order by parentid, id

我使用了 3 个联合词,虽然不太好,但很有效。案例结构会有N个级别,我如何才能得到正确的结果?

【问题讨论】:

标签: sql-server-2008 tree recursive-query


【解决方案1】:
DECLARE @Id int = your_UnitId
;WITH cte AS 
 (
  SELECT a.Id, a.parentId, a.name
  FROM customer a
  WHERE Id = @Id
  UNION ALL
  SELECT a.Id, a.parentid, a.Name
  FROM customer a JOIN cte c ON a.parentId = c.id
  )
  SELECT parentId, Id, name
  FROM cte

SQLFiddle上的演示

【讨论】:

    【解决方案2】:

    如果父 ID 是其自身的子 ID,那么我们需要使用不同的查询。例如,schema 结构如下所示

    CREATE TABLE customer
    (
      id int,
      parentid int,
      name nvarchar(10)
    )
    
    INSERT customer
    VALUES(1,  1, 'aaa'),
      (2,  1,    'bbb'),
      (3,  2,    'ccc'),
      (4,  2,    'ddd'),
      (5,  1,    'eee'),
      (6,  5,    'fff'),
      (7,  5,    'ggg'),
      (8,  8,    'hhh'),
      (9,  8,    'iii'),
      (10, 8,    'jjj')
    

    在这种情况下,我们需要使用以下查询:

    DECLARE @Id int = 1 -- your UnitId
    ;WITH cte AS 
     (
      SELECT a.Id, a.parentId, a.name
      FROM customer a
      WHERE parentid = @Id
      UNION ALL
      SELECT a.Id, a.parentid, a.Name
      FROM customer a JOIN cte c ON a.parentId = c.id
       and c.id != @Id
    
      )
      SELECT parentId, Id, name
      FROM cte
    go
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-29
      • 2022-01-27
      • 2021-06-29
      • 2013-11-23
      • 2021-12-02
      相关资源
      最近更新 更多