我正在尝试在我的桌子上创建一个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
行置于某个地方,但无法弄明白。
更新:这是一个示例数据的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 :(得分: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
本质上,它遍历层次结构,以递归方式调用自身。如果您的输出是针对XML的,那么CTE是不够的。使用这个,以及我可以收集的样本数据,我得到了这个结果:
<Director ID="1" Email="bsmith@someCompany.com" Name="Bob Smith">
<Direct ID="2" Email="jsmith@someCompany.com" Name="Jim Smith">
<Direct ID="4" Email="e1@someCompany.com" Name="Employee 1" />
<Direct ID="5" Email="e2@someCompany.com" Name="Employee 2" />
<Direct ID="7" Email="e4@someCompany.com" Name="Employee 4" />
</Direct>
<Direct ID="3" Email="bjones@someCompany.com" Name="Bob Jones">
<Direct ID="6" Email="e3@someCompany.com" Name="Employee 3" />
<Direct ID="8" Email="e5@someCompany.com" Name="Employee 5" />
<Direct ID="9" Email="e6@someCompany.com" Name="Employee 6" />
</Direct>
</Director>
希望这有帮助。
编辑:最后一分钟SQLFiddle Example。
答案 1 :(得分:-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