2015-07-07 4 views
0

Я хотел бы знать, как создать родительские/дочерние отношения для набора конкретных месяцев, скажем, у нас есть сотрудник Джон, и я хочу знать всех людей, работающих под Джоном, поэтому я бы сделал КТР, как это:SQL Parent Child Relationship

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 

В этом КТР у меня есть конкретный, где состояние, но это не имеет значения, только бизнес-правила :)

Это прекрасно, прекрасно работает на SQL Server 2008 R2, теперь Мне нужно построить отношение иерархии, основанное не только на текущем месяце, мне нужно оглянуться назад, например, два месяца назад.

Если я вижу только один месяц, это нормально, но если я реализую логику, охватывающую более одного месяца, я застрял в круглой ссылке, которая правильна, потому что у Джона могла быть Мария, работающая на него в январе, а также на ту же иерархию происходит в феврале, мой вопрос заключается в том, как я могу построить иерархию, основанную на том, что произошло за определенный промежуток времени, например, с января по февраль.

Я уверен, что есть способ сделать это, но у меня это не :)

К сожалению я предоставлю больше информации об этом. Предположим, мне нужно запустить отчет в период с января по февраль 2015 года, у компании есть иерархия организации в январе, но может быть разной в феврале, потому что один сотрудник меняет своего менеджера или покидает компанию. Таким образом, все эти изменения должны отражаться на моем древовидной структуре за этот период месяца.

Вот пример моего TreeView:

За январь:

John 
    Maria 
     Julia 
    Darin 

В феврале:

John 
    Maria 
     Julia 
     Nicolas 
    Darin 

Если я выбрать дату с января по февраль я должен видеть комбинацию включая в том числе нового сотрудника Николаса в феврале. У меня есть таблица, которая хранит историю каждого месяца, сохраняя иерархию сотрудников/менеджеров, поэтому за каждый месяц я мог бы повторить данные да.

Таблица сотрудников:

EmployeeID INT ManagerID INT PeriodId INT

Столбец PeriodId это число, которое представляет месяц/год так, например, моя иерархия января будет PeriodId = 1, февраль = 2 и т. Д., PeriodId уникален по месяцам/годам.

У меня есть функция значения таблицы с приведенным выше значением CTE, которое получает менеджера и возвращает всех сотрудников под себя и уровень.

Мой КТР включая PeriodId выглядит следующим образом:

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 

Когда я проверяю в течение одного месяца, все это хорошо, но как только я пытаюсь получить данные в течение двух месяцев, например, принимает слишком много времени и повторяя данные более двух раз, даже если я укажу только два месяца.

+3

Просьба представить некоторые примерные данные с ожидаемым выходом. – FutbolFan

+0

У вас есть несколько строк на одного сотрудника с диапазоном дат? Как хранятся ваши данные для таких случаев? (один сотрудник меняет своего менеджера) – thepirat000

+0

может выбрать дату, например, последний день периода, и основывать свою иерархию на том, что вместо диапазона – JamieD77

ответ

1

Если я правильно понял, вопрос можно свести к «как предотвратить круговое обход в запросах CTE».Посмотрите здесь, чтобы ответить: TSQL CTE: How to avoid circular traversal?