【发布时间】:2017-07-02 20:29:20
【问题描述】:
示例表结构:
EmployeeId TeamleaderId TopTeamleaderId LEVEL ParentTree CompanyId
1 0 0 0 NULL 1
2 1 1 1 2>1 1
3 2 1 2 3>2>1 1
TeamleaderId 是foreignKey 对同一张表中EmployeeId 的引用
目标:
每当使用EmployeeId、TeamleaderId、CompanyId 在表中插入一行时,使用AFTER INSERT 触发器自动填充TopTeamleaderId、LEVEL 和ParentTree
代码:
WITH CTE AS (
SELECT EmployeeId, TeamleaderId,0 AS [Level], CAST(EmployeeId AS varchar(100)) AS Heirarchy, TopTeamleaderId
FROM dbo.Employee
WHERE EmployeeId IN (SELECT EmployeeId FROM Employee WHERE TeamleaderId IS NULL
AND CompanyId IN(SELECT DISTINCT CompanyId FROM INSERTED))
UNION ALL
SELECT mgr.EmployeeId, mgr.TeamleaderId, CTE.[Level] +1 AS [Level],
CAST(( CAST(mgr.EmployeeId AS VARCHAR(100)) + '>' + CTE.Heirarchy) AS varchar(100)) AS Heirarchy, CTE.TopTeamleaderId
FROM CTE
INNER JOIN dbo.Employee AS mgr
ON TaskCTE.EmployeeId = mgr.ParentTeamleaderId
)
UPDATE Employee SET [LEVEL] = TC.[LEVEL], ParentTree = TC.Heirarchy, TopTeamleaderId = TC.TopTeamleaderId
FROM dbo.Employee AS Employee
JOIN (SELECT * FROM CTE WHERE EmployeeId IN(SELECT DISTINCT EmployeeId FROM INSERTED) AND ParentTeamleaderId IS NOT NULL) TC
ON
Employee.EmployeeId = TC.EmployeeId
问题: 假设一家公司有 1000000 名员工,这个查询需要很长时间才能执行。如何优化它以便只考虑插入行的父母?
【问题讨论】:
-
您的业务规则是什么?请解释并举例说明。
-
看到规则不清楚,也不清楚您的表格设计的目的。下面的脚本是可以的,但即使从递归 CTE 的角度来看,您的脚本上面也肯定是错误的。它也可以优化。
标签: sql sql-server common-table-expression recursive-query