层次结构中的SQL顶级父记录
我有一张有结构的桌子: CompanyID、CompanyName、LinkedCompanyID 这样,多个公司可以在一个层次结构中链接 e、 g 我想查询返回每个公司的顶级母公司 i、 e 我已经研究了使用递归CTE表达式,但是我能找到的所有示例都返回了从父级向下的层次结构列表,而不是最顶层的父级层次结构中的SQL顶级父记录,sql,sql-server,tsql,common-table-expression,Sql,Sql Server,Tsql,Common Table Expression,我有一张有结构的桌子: CompanyID、CompanyName、LinkedCompanyID 这样,多个公司可以在一个层次结构中链接 e、 g 我想查询返回每个公司的顶级母公司 i、 e 我已经研究了使用递归CTE表达式,但是我能找到的所有示例都返回了从父级向下的层次结构列表,而不是最顶层的父级 任何人都可以提供任何指针或示例查询这仍然可以通过递归CTE实现: CREATE TABLE #Test (CompanyID INT, CompanyName VARCHAR(20), Linke
任何人都可以提供任何指针或示例查询这仍然可以通过递归CTE实现:
CREATE TABLE #Test (CompanyID INT, CompanyName VARCHAR(20), LinkedCompanyID INT)
INSERT INTO #Test
SELECT 1, 'Company A', NULL UNION
SELECT 2, 'Company B', 1 UNION
SELECT 3, 'Company C', 2 UNION
SELECT 4, 'Company D', 2 UNION
SELECT 5, 'Company E', 4 UNION
SELECT 6, 'Company F', 3 UNION
SELECT 7, 'Company G', NULL
;WITH CTE AS
( SELECT *, 0 [Level]
FROM #Test
UNION ALL
SELECT CTE.CompanyID, CTE.CompanyName, #Test.LinkedCompanyID, Level + 1
FROM CTE
INNER JOIN #Test
ON CTE.LinkedCompanyID = #Test.CompanyID
WHERE #Test.LinkedCompanyID IS NOT NULL
)
SELECT c.CompanyID, c.CompanyName, c.LinkedCompanyID
FROM ( SELECT *, MAX([Level]) OVER (PARTITION BY CompanyName) [MaxLevel]
FROM CTE
) c
WHERE MaxLevel = Level
DROP TABLE #Test
试试这个:
Select * , (select CompanyName from Company C_aux where C_Main.LinkedCompanyID = C_aux.CompanyID) as ToplevelParentID
from Company C_Main
强烈建议:添加跟踪“顶部容器”的字段。我在类似的情况下也会这样做(一些intetim KNWDE是他们自己的容器,例如CMS:folter strucure to document,这是一个容器,然后在文档中进行结构。这会变得更简单。谢谢,但这只返回最接近的父级,而不是最高级的父级。这很完美。因此我需要使用交叉应用程序和CTE。我了解CTE部分当然,你能解释一下交叉应用程序做了什么吗?最终的查询只是获取CTE最后一次递归插入的行。实现这一点的方法不止一种(内部连接,存在)但我认为在这种情况下,使用OVER函数是最有效的方法。如果您选择CTE中的*,您应该可以更好地了解最终查询是如何将输出限制到顶级公司的。使用子查询C只是因为窗口函数不能出现在WHERE子句中。
CREATE TABLE #Test (CompanyID INT, CompanyName VARCHAR(20), LinkedCompanyID INT)
INSERT INTO #Test
SELECT 1, 'Company A', NULL UNION
SELECT 2, 'Company B', 1 UNION
SELECT 3, 'Company C', 2 UNION
SELECT 4, 'Company D', 2 UNION
SELECT 5, 'Company E', 4 UNION
SELECT 6, 'Company F', 3 UNION
SELECT 7, 'Company G', NULL
;WITH CTE AS
( SELECT *, 0 [Level]
FROM #Test
UNION ALL
SELECT CTE.CompanyID, CTE.CompanyName, #Test.LinkedCompanyID, Level + 1
FROM CTE
INNER JOIN #Test
ON CTE.LinkedCompanyID = #Test.CompanyID
WHERE #Test.LinkedCompanyID IS NOT NULL
)
SELECT c.CompanyID, c.CompanyName, c.LinkedCompanyID
FROM ( SELECT *, MAX([Level]) OVER (PARTITION BY CompanyName) [MaxLevel]
FROM CTE
) c
WHERE MaxLevel = Level
DROP TABLE #Test
Select * , (select CompanyName from Company C_aux where C_Main.LinkedCompanyID = C_aux.CompanyID) as ToplevelParentID
from Company C_Main