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这么简单。正如你所看到的,我对它们几乎没有经验:(只是想说这确实帮助了我。需要一个自上而下和自下而上的多对多递归查询。有了它,它很容易工作。