我有3个数据表:有些人可以访问一个分支,而分支可以有一些子分支
ID PName
1 P1
2 P2
ID Title BrachIDRef
0 Master null
1 B1 0
2 B2 1
3 B3 2
4 B4 2
5 B5 1
6 B6 0
7 B7 6
Id PersonIDref BranchIDref
1 1 1
2 2 6
3 2 2
我需要的结果是像这样在SQL Server查询中访问人员和分支和子分支:
P1 B1
P1 (and All Childs of B1 - for each child have a record of data)
P2 B6
P2 and All Childs if B6
P2 B2
P2 and All Childs Of B2
答案 0 :(得分:1)
您需要对Branchs表使用递归CTE,并且需要使用ROW_NUMBER()生成动态唯一记录ID,该ID将使用订单记录。
在UNION ALL选择查询之前,将生成具有记录ID的父记录值。 在UNION ALL选择查询之后,将基于父记录生成子记录。
请在下面的查询中查询您的预期结果。
SELECT * INTO #Persons
FROM (
SELECT '1' ID,'P1' PName UNION ALL
SELECT '2','P2') a
SELECT * INTO #Branches
FROM (
SELECT '0' ID,'Master' Title,NULL BrachIDRef UNION ALL
SELECT '1','B1','0' UNION ALL
SELECT '2','B2','1' UNION ALL
SELECT '3','B3','2' UNION ALL
SELECT '4','B4','2' UNION ALL
SELECT '5','B5','1' UNION ALL
SELECT '6','B6','0' UNION ALL
SELECT '7','B7','6'
) a
SELECT * INTO #PersonBranches
FROM (
SELECT '1' Id,'1' PersonIDref,'1' BranchIDref UNION ALL
SELECT '2' Id,'2' PersonIDref,'6' BranchIDref UNION ALL
SELECT '3' Id,'2' PersonIDref,'2' BranchIDref
) a
;WITH branchCTE
AS
(
SELECT
B.ID,B.Title,B.BrachIDRef,P.PName,ROW_NUMBER() OVER (ORDER BY B.BrachIDRef,B.ID) AS RID
FROM #Branches B
INNER JOIN #PersonBranches PB ON PB.BranchIDref = B.ID
INNER JOIN #Persons P ON P.ID = PB.PersonIDref
UNION ALL
SELECT
B1.ID,B1.Title,B1.BrachIDRef,C.PName,C.RID
FROM #Branches B1
INNER JOIN branchCTE C ON C.ID = B1.BrachIDRef
WHERE B1.BrachIDRef > 0
)
SELECT
C.PName,
C.Title
FROM branchCTE C
ORDER BY C.RID
DROP TABLE #Persons;
DROP TABLE #Branches;
DROP TABLE #PersonBranches;
答案 1 :(得分:-1)
您可以使用具有不同CTE的connect by before并将其与常规查询合并,以按以下方式获取所有子项:
cte as
(SELECT ANCESTOR,
LISTAGG(case when Title = ANCESTOR then null else title end, '/') within group (order by null) as pth from
(SELECT DISTINCT ID,
CONNECT_BY_ROOT Title as ANCESTOR,
Title
FROM Branches
CONNECT BY PRIOR ID = BrachIDRef)
GROUP BY
ANCESTOR)
--
SELECT pb.id, p.pname, b.title
from PersonBranches pb
join persons p on (p.id = pb.PersonIDref)
join Branches b on (pb.BranchIDref = b.id)
union all
SELECT pb.id, p.pname, c.pth
from PersonBranches pb
join persons p on (p.id = pb.PersonIDref)
join Branches b on (pb.BranchIDref = b.id)
join cte c on (b.title = c.ANCESTOR)
order by id;
干杯!