【问题标题】:SQL Server Recursion Max LevelSQL Server 递归最大级别
【发布时间】:2012-02-21 11:47:45
【问题描述】:

我在 SQL 2008 中有一个基本的递归表设置,其结构如下:

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

当我在没有“WHERE Depth

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

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 个子级别,而其他级别无关紧要。

任何帮助将不胜感激!

【问题讨论】:

    标签: sql sql-server-2008 recursion


    【解决方案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
    

    【讨论】:

    • 效果很好。我一直在尝试与以前类似的东西,但是除了深度之外,我在外部查询中还有“WHERE Id = 2 ...”,这给我带来了一些奇怪的问题。无论出于何种原因,一旦我意识到必须将另一部分移入,我就没有尝试将深度部分移出。无论如何,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 2020-05-28
    • 1970-01-01
    • 2018-10-04
    • 2013-03-24
    相关资源
    最近更新 更多