2012-01-29 107 views
0

我在2008年SQL具有以下结构的基本递归表设置:SQL服务器递归最高级别

CREATE TABLE [dbo].[Employee] 
(
[Id] [int] IDENTITY(1,1) NOT NULL, 
[Name] [nvarchar](100) NOT NULL, 
[ManagerId] [int] NULL, 
CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED ([Id] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

ALTER TABLE [dbo].[Employee] WITH CHECK ADD CONSTRAINT [FK_Employee_Employee] FOREIGN KEY([ManagerId]) REFERENCES [dbo].[Employee] ([Id]) 

基于几个不同的文章在网上,我发现在那里我可以编写一个查询,如之后返回一个“经理”和下面包含的所有子记录:

WITH DirectRelationships AS 
(
SELECT Id, Name, ManagerId, Depth = 0 
FROM Employee 
WHERE ManagerId = 1 
UNION ALL 
SELECT e.Id, e.Name, e.ManagerId, Depth = Depth + 1 
FROM Employee e 
INNER JOIN DirectRelationships DR ON DR.Id = e.ManagerId 
WHERE Depth <= 2 /* this doesn't work */ 
) 
SELECT * FROM DirectRelationships 

当我运行上面的select语句没有“WHERE深度< = 2”我得到四列背(ID,姓名,经理ID,深度)显示我正在寻找的确切记录。我遇到的问题是Depth基于根记录的总体深度(其中ManagerId为null),而不是记录来自请求管理器的深度。

例如,假设我有此表中的以下数据:

select * from Employee; 

Id | Name    | ManagerId | Depth 
------------------------------------------ 
1 CEO     0   0 
2 National Director 1   1 
3 Regional Director 2   2 
4 Store Director  3   3 
5 Clerk    4   4 
6 Clerk #2   4   4 

我想我的查询能够做的就是让一个经理级别(比如,全国总监或ID#2)指定递归拉的级数(比如2)。这将返回以下内容:

Id | Name    | ManagerId | Depth 
------------------------------------------ 
2 National Director 1   0 /*top level requested */ 
3 Regional Director 2   1 /*new depth based on requested parent */ 
4 Store Director  3   2 /*new depth based on requested parent */ 

所以我不会得到顶级CEO的位置,我也不会得到个别职员,因为我只想要一个特定条目和2级低于。我已经看到了你可以在查询中指定MAXRECURSION的位置,但是如果级别超过了你指定的数量,那就会引发错误,这是不可取的。我要处理的层次结构可能有成千上万的记录,对于任何特定的实体列表,我只想要最多5个子级别,其他则不相关。

任何帮助将不胜感激!

回答

1

尝试运行:

WITH DirectRelationships AS 
(
    SELECT Id, Name, ManagerId, Depth = 0 
    FROM Employee 
    WHERE Id = 2 

    UNION ALL 

    SELECT e.Id, e.Name, e.ManagerId, Depth = Depth + 1 
    FROM Employee e 
     INNER JOIN DirectRelationships DR ON DR.Id = e.ManagerId 
) 
SELECT * 
FROM DirectRelationships 
WHERE Depth <= 2 

你应该得到你正在寻找的结果:这工作完全

Id Name    ManagerId Depth 
-- ----------------- --------- ----- 
2 National Director 1   0 
3 Regional Director 2   1 
4 Store Director 3   2 
+0

。我一直在尝试与之前类似的东西,但除了深度之外,我还在外部查询中使用了“WHERE ID = 2 ...”,这对我造成了一些奇怪的问题。无论出于何种原因,当我意识到必须移动另一部分时,我还没有尝试移动深度部分。无论如何,谢谢! – RubyHaus 2012-01-29 16:48:52