具有完整层次结构的SQL递归

时间:2017-02-27 13:42:12

标签: sql-server recursion

这就是我现在的查询:

with allmembers (objectid, parentid, name, parentname, recursion) as 
(
-- anchor elements: where parentid = 25
select objectid, parentid, name, name as parentname, 0 as recursion
from orgs as orgs1 
where parentid = 25 

-- recursion begins here
union all 
select orgs2.objectid, orgs2.parentid, orgs2.name, orgs3.name as parentname, recursion + 1
from orgs as orgs2 
    join allmembers as orgs3 on orgs2.parentid = orgs3.objectid
)
-- we select all the results 
select *
from allmembers 

它从列表中选择组织(组织),其中parentid为25(这些是"根组织")并且递归地将它们与所有子组织连接,直到没有剩下。所以我们得到了一个组织及其父母的名单。

我的问题是我只获得了直接子/父母关系:

  

名称| parentname

     

销售| All_Employees

     

直接销售|销售

在这个过程中失去的是"直接销售"也是" All_Employees",间接,通过"销售"的成员。 所以我宁愿添加以下结果:

  

名称| parentname

     

销售| All_Employees

     

直接销售|销售

     

直接销售| All_Employees

如何实现这一目标?

1 个答案:

答案 0 :(得分:0)

如果没有走得太远并且涉及到功能,那么使用物化路径是否足以满足您的需求?

create table orgs (objectid int, name varchar(128), parentid int);
insert into orgs values
 (26,'All Employees', 25)
,(27,'Sales', 26)
,(28,'Direct Sales',27);

with allmembers as (
-- anchor elements: where parentid = 25
  select 
      objectid
    , parentid
    , name
    , parentname = convert(varchar(128),'')
    , rootname   = name
    , recursion  = convert(int,0)
    , name_path  = convert(varchar(256),name)
  from orgs  
  where parentid = 25 
  -- recursion begins here
  union all 
  select 
      c.objectid
    , c.parentid
    , c.name
    , parentname = p.name
    , rootname   = p.rootname
    , recursion  = p.recursion + 1
    , name_path  = convert(varchar(256),p.name_path + ' > ' + c.name)
  from orgs as c 
      join allmembers as p on c.parentid = p.objectid
)
-- we select all the results 
select *
from allmembers 

返回:

+----------+----------+---------------+---------------+---------------+-----------+--------------------------------------+
| objectid | parentid |     name      |  parentname   |   rootname    | recursion |              name_path               |
+----------+----------+---------------+---------------+---------------+-----------+--------------------------------------+
|       26 |       25 | All Employees |               | All Employees |         0 | All Employees                        |
|       27 |       26 | Sales         | All Employees | All Employees |         1 | All Employees > Sales                |
|       28 |       27 | Direct Sales  | Sales         | All Employees |         2 | All Employees > Sales > Direct Sales |
+----------+----------+---------------+---------------+---------------+-----------+--------------------------------------+