2014-09-30 2 views
0

Я пытаюсь создать CTE на моем столе, чтобы привлечь иерархию сотрудников.Иерархия TSQL CTE

У меня есть отправная точка, которая является «Директором», и я хочу найти всех, кто подчиняется каждому из них.

Вот то, что я до сих пор:

;WITH EmpTable_CTE (FirstName, LastName, QID, Email) AS 
    (
     SELECT  FirstName, 
        LastName, 
        QID, 
        Email 
     FROM  EmployeeTable E 
     WHERE  QID = '12345' 

     UNION ALL 

     SELECT  E.FirstName, 
        E.LastName, 
        E.QID, 
        E.Email 
     FROM  EmployeeTable E 
     INNER JOIN EmpTable_CTE AS E2 ON E.MgrQID = E2.QID 
    ) 
    SELECT * FROM EmpTable_CTE 

Это похоже на работу предоставляя мне список сотрудников, но нет «иерархии» к нему.

Как я могу использовать FOR XML для создания иерархии, которую я ищу?

<Director>Bob Smith</Director> 
    <Direct>Jim Smith</Direct> 
     <Direct>Employee 1</direct> 
     <Direct>Employee 2</direct> 
     <Direct>Employee 3</direct> 
    <Direct>Bob Jones</Direct> 
     <Direct>Employee 1</direct> 
     <Direct>Employee 2</direct> 
     <Direct>Employee 3</direct> 
      <Direct>Employee A</direct> 

Я уверен, что его просто вопрос размещения FOR XML линии где-то, но не могу вполне понять это.

Update: Вот SQL Скрипка данных выборки:

http://sqlfiddle.com/#!6/a48f6/1

Это, как я ожидаю, что данные были из скрипки:

<Director>Jim Jones</Director> 
    <Direct>Bob Jones</Direct> 
     <Direct>Jake Jones</Direct> 
     <Direct>Smith Jones</Direct> 
      <Direct>Carl Jones</Direct> 
       <Direct>Bobby Jones</Direct> 
    <Direct>Danny Jones</Direct> 
     <Direct>Billy Jones</Direct> 
+0

Использовать порядок, чтобы получить иерархию –

+0

Текущий вывод - это только таблица результатов, он не выводит структуру XML вообще – SBB

+0

вы можете предоставить некоторые данные примера? –

ответ

1

Часть трудности в структуре XML вы представили - если вы передали это в парсер, все было бы плоской и выполнив результаты моего процесса ниже, не набив имя First и Last в атрибут, чтобы узлы выходили в смешанном контенте (текст с узлами на одном и том же уровень).

Итак, я искал и нашел this little gem here on SE. Адаптация его к вашим потребностям, и бросали в нескольких областях, как атрибуты из вашей таблицы, я пришел с этим:

CREATE FUNCTION dbo.EmpHierarchyNode(@QID int) 
RETURNS XML 
WITH RETURNS NULL ON NULL INPUT 
BEGIN RETURN 
    (SELECT QID AS "@ID", Email AS "@Email", 
    FirstName + ' ' + LastName AS "@Name", 
     CASE WHEN MgrQID = @QID 
     THEN dbo.EmpHierarchyNode(QID) 
     END 
    FROM dbo.EmployeeTable 
    WHERE MgrQID = @QID 
    FOR XML PATH('Direct'), TYPE) 
END 

SELECT QID AS "@ID", Email AS "@Email", 
    FirstName + ' ' + LastName AS "@Name", 
    dbo.EmpHierarchyNode(QID) 
FROM dbo.EmployeeTable 
WHERE MgrQID IS NULL 
FOR XML PATH('Director'), TYPE 

По существу, это проходит вниз в иерархии, рекурсивно, называющая себя. CTE недостаточно, если ваш результат предназначен для XML. Используя это, и то, что я мог бы почерпнуть из данных образцов, я получил это в результате:

<Director ID="1" Email="[email protected]" Name="Bob Smith"> 
    <Direct ID="2" Email="[email protected]" Name="Jim Smith"> 
    <Direct ID="4" Email="[email protected]" Name="Employee 1" /> 
    <Direct ID="5" Email="[email protected]" Name="Employee 2" /> 
    <Direct ID="7" Email="[email protected]" Name="Employee 4" /> 
    </Direct> 
    <Direct ID="3" Email="[email protected]" Name="Bob Jones"> 
    <Direct ID="6" Email="[email protected]" Name="Employee 3" /> 
    <Direct ID="8" Email="[email protected]" Name="Employee 5" /> 
    <Direct ID="9" Email="[email protected]" Name="Employee 6" /> 
    </Direct> 
</Director> 

Надеется, что это помогает.

EDIT: Last Minute SQLFiddle Example.

-1

, что он соответствует вашим требование:

;WITH EmpTable_CTE (FirstName, LastName, QID, Email) AS 
    (
     SELECT  FirstName, 
        LastName, 
        QID, 
        Email 
     FROM  EmployeeTable E 
     WHERE  QID = 1 
     UNION ALL 
     SELECT  E.FirstName, 
        E.LastName, 
        E.QID, 
        E.Email 
     FROM  EmployeeTable E 
     INNER JOIN EmpTable_CTE AS E2 
     ON   E.MgrQID = E2.QID 
    ) 

    SELECT LastName + ', ' + FirstName FROM EmpTable_CTE FOR XML PATH('Direct'), ROOT('Director'), TYPE 
+0

Это не так, это просто добавляет тег вокруг каждого из имен. – SBB

+0

Это даст только один уровень, похоже, что OP хочет иерархическую базу на уровнях – radar

+0

В этом случае мы должны использовать функции, как это было упомянуто здесь http://stackoverflow.com/questions/14765937/cte-and-for-xml -в-сгенерировать-вложенный-XML –

Смежные вопросы