这看起来有点傻,但我想一次尝试解决这个问题。
我在SQL数据库中有一个表链接回自身。它具有组织ID和父组织ID。顶级组织的父ID为0,并且不同级别的每个组织都具有其上一个组织的父组织。组织的级别曾经由名为org Level的表中的另一个字段确定。但是,现在水平取决于组织树的下降距离。这样,如果一个组织的父母有另一个父母,那么第一个组织将处于3级,它的父级位于2级,而它的祖父母级别为1级。
我理解我希望我的SQL如何工作,但问题是创建一个通用的SQL语句,它会返回组织及其级别。我决定尝试使用XML来做到这一点,但这可能不是最好的主意。假设我有一个这样的组织结构。
-Top Org 1
--Second Org 1
--Second Org 2
-Top Org 2
--Second Org 3
--Second Org 4
-Top Org 3
--Second Org 5
--Second Org 6
完成后,我想查询如下所示的XML:
<Organizations>
<Lvl1 OrgID="1" Name="Top Level 1" Index="1">
<Lvl2 OrgID="5" Name="Second Level 1" Index="1" />
<Lvl2 OrgID="6" Name="Second Level 2" Index="2" />
</Lvl1>
<Lvl1 OrgID="3" Name="Top Level 2" Index="2">
<Lvl2 OrgID="7" Name="Second Level 3" Index="1" />
<Lvl2 OrgID="8" Name="Second Level 4" Index="2" />
</Lvl1>
<Lvl1 OrgID="4" Name="Top Level 3" Index="3">
<Lvl2 OrgID="9" Name="Second Level 5" Index="1" />
<Lvl2 OrgID="10" Name="Second Level 6" Index="2" />
</Lvl1>
</Organizations>
如果我知道要查询多少级别,我已经弄清楚我想要如何正常执行此操作。如果我想查询第一级和第二级,我会这样做:
SELECT
Lvl1.Org_ID [@OrgID]
,Lvl1.Org_Name [@Name]
,Lvl1.Org_SortID [@Index]
,(
SELECT
Lvl2.Org_ID [@OrgID]
,Lvl2.Org_Name [@Name]
,Lvl2.Org_SortID [@Index]
FROM Organizations Lvl2
WHERE Lvl2.Org_ParentID = Lvl1.Org_ID
GROUP BY Lvl2.Org_ID, Lvl2.Org_Name, Lvl2.Org_SortID
ORDER BY Lvl2.Org_SortID
FOR XML PATH('Lvl2'), TYPE
)
FROM Organizations Lvl1
INNER JOIN Organizations Child1 ON Lvl1.Org_ID = Child1.Org_ParentID
WHERE Lvl1.Org_ParentID = 0
GROUP BY Lvl1.Org_ID, Lvl1.Org_Name, Lvl1.Org_SortID
ORDER BY Lvl1.Org_SortID
FOR XML PATH('Lvl1'), ROOT('Organizations')
但是让我假装我不知道我会有多少级别。我可能只有两个级别,我可能有15个级别。并非每个组织都可以拥有相同数量的级别。我想知道的是,如果有一种方法可以递归地查看每个记录,并确定它是否有任何子记录。如果是这样,为这些孩子创建新的XML标签并向下钻取一个级别,然后检查每个孩子并查看他们是否有孩子。等。
也许没有一种好的方法可以做到这一点,或许多是一个巨大的内存和时间汇,使SQL做这样的事情。但如果不是,请告诉我这是可能的并向我展示一个例子。谢谢!
答案 0 :(得分:2)
我最近有类似的问题,我通过使用递归函数解决了问题(即它自己调用)。
我没有做过任何测试,但这样的事情应该有效:
CREATE FUNCTION dbo.GetChildOrganisations (@ParentID INT)
RETURNS XML
AS
BEGIN
RETURN
( SELECT Org_ID [@OrgID],
Org_Name [@Name],
Org_SortID [@Index],
dbo.GetChildOrganisations(Org_ID) [ChildOrganisations]
FROM Organizations
WHERE Org_ParentID = @ParentID
FOR XML PATH('Orgainisations')
)
END