SQL父子关系

时间:2015-07-07 21:05:29

标签: sql sql-server sql-server-2008

我想知道如何为一组特定月份创建父/子关系,假设我们有一名员工John,我想知道所有在John下工作的人,所以我会做这样的CTE :

WITH CTE
AS 
(
    SELECT @EmployeeIdTmp as EmployeeId,
           0 AS [Level]

     UNION ALL

    SELECT em.[EmployeeId],
           [Level] + 1
      FROM Employee em
     INNER JOIN CTE t 
        ON em.[ManagerId] = t.EmployeeId
     WHERE (em.[ManagerId] <> em.[EmployeeId] 
       AND em.[ManagerId] IS NOT NULL)
)

SELECT EmployeeId, [Level]
  FROM CTE

在这个CTE中,我有一个具体的条件,但只是业务规则并不重要:)

这很好,在SQL Server 2008 R2上完美运行,现在我需要根据当前月份构建我的层次结构关系,我需要回顾两个月前的例子。

如果我只看到一个月就可以了,但是如果我实施一个逻辑来覆盖超过一个月,我会陷入一个循环引用,这是正确的,因为约翰可能让玛丽亚在1月为他工作,同样的等级发生2月,我的问题是如何根据一段时间内发生的事情建立一个等级,例如在1月到2月之间。

我确信有办法做到这一点,但我的不是:)

抱歉,我会提供更多相关数据。假设我需要在2015年1月到2月期间运行报告,公司在1月份有一个组织层级,但在2月可能会有所不同,因为一名员工改变了他的经理或离开了公司。因此,所有这些变化都需要在我的树视图中反映出来。

这是我的树视图的一个例子:

1月:

John
   Maria
      Julia
   Darin

二月:

John
   Maria
      Julia
      Nicolas
   Darin

如果我从1月到2月选择一个日期,我应该看到两者的组合,包括2月份的新员工尼古拉斯。我有一个表保存每个月的历史记录保持员工/经理的层次结构,所以每个月我可以重复数据是。

表员工:

EmployeeId int ManagerId int PeriodId int

PeriodId列是一个代表月/年的数字,例如我的1月层次结构将具有PeriodId = 1,2月= 2等等,PeriodId按月/年唯一。

我有一个上面有CTE的表值函数,它接收一个经理并返回他下面的所有员工和级别。

包括PeriodId在内的我的CTE如下所示:

WITH CTE
AS 
(
    SELECT @EmployeeIdTmp as EmployeeId,
           0 AS [Level]

     UNION ALL

    SELECT em.[EmployeeId],
           [Level] + 1
      FROM Employee em
     INNER JOIN @PeriodIds p
        ON em.[PeriodId] = p.[PeriodId]
     INNER JOIN CTE t 
        ON em.[ManagerId] = t.EmployeeId
     WHERE (em.[ManagerId] <> em.[EmployeeId] 
       AND em.[ManagerId] IS NOT NULL)
)

SELECT EmployeeId, [Level]
  FROM CTE

当我检查一个月时,一切都很好,但是一旦我尝试获取两个月的数据,就是花费太多时间并且重复数据超过两次,即使我指定了仅仅两个月。

1 个答案:

答案 0 :(得分:1)

如果我理解正确,问题可以简化为&#34;如何防止CTE查询中的循环遍历&#34;。在这里寻找答案:TSQL CTE: How to avoid circular traversal?