22

我有这样的结构:

<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个级别,我如何获得正确的结果?

4

2 回答 2

48
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上的演示

于 2012-12-14T15:27:56.157 回答
2

如果父 id 是其自身的孩子,那么我们需要使用不同的查询。例如,模式结构如下

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
于 2018-07-06T02:13:39.787 回答