我在SQL Server 2005中有一个包含员工的层次结构表 - >经理 - >部门 - >位置 - >状态。
层次结构表的示例表:
ID Name ParentID Type
1 PA NULL 0 (group)
2 Pittsburgh 1 1 (subgroup)
3 Accounts 2 1
4 Alex 3 2 (employee)
5 Robin 3 2
6 HR 2 1
7 Robert 6 2
第二个是事实表,其中包含员工薪资详细信息ID和薪水。
事实表的示例数据:
ID Salary
4 6000
5 5000
7 4000
是否有任何方法可以显示层次结构表中的层次结构,并根据员工汇总工资总和。预期结果如
Name Salary
PA 15000 (Pittsburgh + others(if any))
Pittusburgh 15000 (Accounts + HR)
Accounts 11000 (Alex + Robin)
Alex 6000 (direct values)
Robin 5000
HR 4000
Robert 4000
在我的生产环境中,层次结构表可能包含23000多行,而事实表可能包含300,000多行。因此,我考虑向查询提供任何级别的groupid以仅检索其子级及其相应的聚合值。有更好的解决方案吗?
答案 0 :(得分:0)
此解决方案可生成正确的结果。只要索引到位,这应该对您的生产数据集执行正常,但我没有对您的示例数据进行测试。
DECLARE @tree TABLE
(ID INT
,name VARCHAR(15)
,ParentID INT
,TYPE TINYINT
)
DECLARE @salary TABLE
(ID INT
,Salary INT
)
INSERT @tree
SELECT 1,'PA',NULL,0
UNION SELECT 2,'Pittsburgh',1,1
UNION SELECT 3,'Accounts',2,1
UNION SELECT 4,'Alex',3,2
UNION SELECT 5,'Robin',3,2
UNION SELECT 6,'HR',2,1
UNION SELECT 7,'Robert',6,2
INSERT @salary
SELECT 4,6000
UNION SELECT 5,5000
UNION SELECT 7,4000
;WITH salaryCTE
AS
(
SELECT t.*
,s.Salary
FROM @tree AS t
LEFT JOIN @salary AS s
ON s.ID = t.ID
)
,recCTE
AS
(
SELECT t.ID
,CAST(t.name AS VARCHAR(MAX)) AS name
,t.ParentID
,ISNULL(t.Salary,0) AS Salary
,0 AS LEVEL
,CAST(t.ID AS VARCHAR(100)) AS ord
FROM salaryCTE AS t
WHERE t.ParentID IS NULL
UNION ALL
SELECT t.ID
,CAST(REPLICATE(' ',r.LEVEL) + t.name AS VARCHAR(MAX)) AS name
,t.ParentID
,ISNULL(t.Salary,0) AS Salary
,r.LEVEL + 1
,CAST(r.ord + '|' + CAST(t.ID AS VARCHAR(11)) AS VARCHAR(100)) AS ord
FROM salaryCTE AS t
JOIN recCTE AS r
ON r.ID = t.ParentID
)
SELECT name
,salary
FROM (
SELECT r1.name
,r1.ord
,SUM(r2.salary) AS salary
FROM recCTE AS r1
LEFT JOIN recCTE AS r2
ON r2.ord LIKE r1.ord + '%'
GROUP BY r1.name,r1.ord
) AS x
ORDER BY ord,name