我如何重新设计下面的查询,以便它递归遍历整个树以返回从root到leaves的所有后代? (我正在使用SSMS 2008)。我们有一位总统。在他之下是副总裁,然后是高层管理人员等。我需要返回每个的名称和标题。但是这个查询不应该是硬编码的;我需要能够为任何选定的员工运行此项服务,而不仅仅是总裁。下面的查询是硬编码方法。
select P.staff_name [Level1],
P.job_title [Level1 Title],
Q.license_number [License 1],
E.staff_name [Level2],
E.job_title [Level2 Title],
G.staff_name [Level3],
G.job_title [Level3 Title]
from staff_view A
left join staff_site_link_expanded_view P on P.people_id = A.people_id
left join staff_site_link_expanded_view E on E.people_id = C.people_id
left join staff_site_link_expanded_view G on G.people_id = F.people_id
left join facility_view Q on Q.group_profile_id = P.group_profile_id
谢谢,这与我需要的最匹配。以下是我的CTE查询:
with Employee_Hierarchy (staff_name, job_title, id_number, billing_staff_credentials_code, site_name, group_profile_id, license_number, region_description, people_id)
as
(
select C.staff_name, C.job_title, C.id_number, C.billing_staff_credentials_code, C.site_name, C.group_profile_id, Q.license_number, R.region_description, A.people_id
from staff_view A
left join staff_site_link_expanded_view C on C.people_id = A.people_id
left join facility_view Q on Q.group_profile_id = C.group_profile_id
left join regions R on R.regions_id = Q.regions_id
where A.last_name = 'kromer'
)
select C.staff_name, C.job_title, C.id_number, C.billing_staff_credentials_code, C.site_name, C.group_profile_id, Q.license_number, R.region_description, A.people_id
from staff_view A
left join staff_site_link_expanded_view C on C.people_id = A.people_id
left join facility_view Q on Q.group_profile_id = C.group_profile_id
left join regions R on R.regions_id = Q.regions_id
WHERE C.STAFF_NAME IS NOT NULL
GROUP BY C.STAFF_NAME, C.job_title, C.id_number, C.billing_staff_credentials_code, C.site_name, C.group_profile_id, Q.license_number, R.region_description, A.people_id
ORDER BY C.STAFF_NAME
但我想知道“Employee_Hierarchy”的目的是什么?当我用“Employee_Hierarchy”替换外部查询中的“staff_view”时,它只返回一条记录=“Kromer”。那么我们何时/何地可以使用“Employee_Hierarchy”?
答案 0 :(得分:3)
请参阅:
<强>更新强>
正确的递归CTE基本上由三件事组成:
锚 SELECT
开头;可以选择例如根级员工(Reports_To
为NULL),或者可以选择您定义的任意员工,例如通过参数
UNION ALL
递归 SELECT
语句,该语句从相同的,通常为自引用的表中进行选择,并与当前构建的递归CTE连接
这使您能够递归地构建一个结果集,然后可以从中选择。
如果查看Northwind
示例数据库,它会有一个名为Employees
的表格,该表格是自引用的:Employees.ReportsTo --> Employees.EmployeeID
定义了谁向谁报告。
您的CTE看起来像这样:
;WITH RecursiveCTE AS
(
-- anchor query; get the CEO
SELECT EmployeeID, FirstName, LastName, Title, 1 AS 'Level', ReportsTo
FROM dbo.Employees
WHERE ReportsTo IS NULL
UNION ALL
-- recursive part; select next Employees that have ReportsTo -> cte.EmployeeID
SELECT
e.EmployeeID, e.FirstName, e.LastName, e.Title,
cte.Level + 1 AS 'Level', e.ReportsTo
FROM
dbo.Employees e
INNER JOIN
RecursiveCTE cte ON e.ReportsTo = cte.EmployeeID
)
SELECT *
FROM RecursiveCTE
ORDER BY Level, LastName
我不知道你是否可以将你的样本翻译成适当的递归CTE - 但这基本上是它的要点:锚点查询,UNION ALL,递归查询