Sql 递归查询帮助

Sql 递归查询帮助,sql,sql-server,sql-server-2008,recursion,Sql,Sql Server,Sql Server 2008,Recursion,我的数据库模式中有两个表,它们表示一个与自身有多对多关系的实体 Role --------------------- +RoleID +Name RoleHasChildRole --------------------- +ParentRoleID +ChildRoleID 基本上,我需要能够编写这样的查询: 给定一组角色,递归返回所有相关角色的唯一集合。 这是一个MSSQL 2008数据库 编辑: 要求提供一些样本数据。下面是: RoleID Name -------

我的数据库模式中有两个表,它们表示一个与自身有多对多关系的实体

Role  
---------------------
+RoleID 
+Name

RoleHasChildRole
---------------------
+ParentRoleID  
+ChildRoleID  
基本上,我需要能够编写这样的查询:

给定一组角色,递归返回所有相关角色的唯一集合。

这是一个MSSQL 2008数据库

编辑:

要求提供一些样本数据。下面是:

RoleID    Name
------------------------------------
1         'Admin'
2         'SuperUser'
3         'Lackey'
4         'Editor'
5         'CanEditSomething'
6         'CanDeleteSomething'
7         'CanCreateSomething'
8         'CanViewSomething'

ParentRoleID    ChileRoleID
------------------------------------
1               5
1               6
1               7
1               8
2               4
4               5
4               8
因此,对管理员角色的查询将返回:

“管理员”
“CanEditSomething”
“烛光之物”
“可以创建一些东西”
“能看到一些东西”

对超级用户的查询将返回:

“超级用户”
“编辑”
“可以查看某些内容”
“CanEditSomething”

我的QCD(快速、廉价和肮脏)示例:

假设组织中存在简单的员工-经理关系。我们将有一个EmployeeManager表EmpMan,它有两列EmpID和ManID。为了简单起见,我将省略其他细节(索引、包含员工姓名/联系人的辅助表等)

CREATE TABLE [dbo].[EmpMan]( [EmpID] [int] NOT NULL, [ManID] [int] NOT NULL) GO;

   insert into dbo.EmpMan   select 2,1

union select 3,1
union select 4,1 
union select 31,3 
union select 32,2
union select 43,4   `/* 3X report to 3 and 4X report to 4*/`

union select 310,31 
union select 314,31 `/* 31X reports to 31*/`

union  select 56,5 union select 87,8 `/*empID 56 reports to 5 and 87 reports to  8, 5 and 8 do not have managers*/`
CTE查询可以执行递归查询:

with Manager AS (

/*initialization query*/

select  EmpID,ManID from EmpMan where ManID=1/* assuming that your VP ID is 1, or it can be the top most person whom you want to query on*/

union all

/*recursive query*/

select E.EmpID,E.ManID from EmpMan E

join Manager M on  E.ManID=M.EmpID)

select * from Manager

非常常见的CTE用法:

WITH RecursiveRole AS (
  SELECT RoleID AS RecursiveRoleID
  FROM Role
  WHERE Name = @parameter

  UNION ALL

  SELECT ChildRoleID AS RecursiveRoleID
  FROM RoleHasChildRole
  INNER JOIN RecursiveRole
    ON RoleHasChildRole.ParentRoleID = RecursiveRole.RecursiveRoleID
)
SELECT RoleID, RoleName
FROM RecursiveRole
INNER JOIN Role
  ON RecursiveRoleID = RoleID
这只会进入角色树。我留下来做一个作为练习的


EDIT看起来你只是想从树上下来。这个查询做得很好

返回测试数据的以下结果:

SET @parameter = 'Admin'
1   Admin
5   CanEditSomething
6   CanDeleteSomething
7   CanCreateSomething
8   CanViewSomething

SET @parameter = 'SuperUser'
2   SuperUser
4   Editor
5   CanEditSomething
8   CanViewSomething

向我们展示一些示例数据,或者您到目前为止已经尝试了什么…我不确定添加示例数据会带来什么好处。这种结构是不言而喻的。至于递归查询,我已经看过CTE示例,但它们似乎都处理一个自引用的表。示例数据将向我们展示您的结构中是否有循环……同意astander的说法:我不知道您在寻找什么。我们需要一些数据。我用CTEI编了一个例子,我将使用一个约束来确保没有无限循环。太棒了!没想到CTE这么简单。正如你所看到的,我对它们几乎没有经验:(只是想说这确实帮助了我。需要一个自上而下和自下而上的多对多递归查询。有了它,它很容易工作。