Как создать рекурсивный запрос SQL? - PullRequest
0 голосов
/ 12 декабря 2011

Как мне изменить дизайн приведенного ниже запроса, чтобы он рекурсивно проходил по всему дереву, возвращая всех потомков от корня к листьям?(Я использую 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"?Когда я заменил "staff_view" во внешнем запросе на "Employee_Hierarchy", он вернул только одну запись = "Kromer".Так, когда / где мы можем использовать «Employee_Hierarchy»?

1 Ответ

3 голосов
/ 12 декабря 2011

См:

Обновление:

Правильный рекурсивный CTE состоит в основном из трех вещей:

  • и якорь SELECT для начала; который может выбрать, например, сотрудники корневого уровня (где Reports_To равно NULL), или он может выбрать любого произвольного сотрудника, которого вы определили, например, по параметру

  • a UNION ALL

  • a рекурсивный оператор 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, рекурсивный запрос

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...