我认为我不太了解递归查询。我看到的经典递归查询是经理和员工递归查询。我正在使用该查询来捕获整个层次结构,但是我想进行查询,以使我能够捕获所有父级,子级及其级别(相对于顶层)。我感觉我需要对递归查询进行递归吗?
WITH RECURSIVE
tree AS (
SELECT
id_employee,
id_manager,
0 AS level
FROM
people
WHERE
id_manager = '00001'--this is the boss of all bosses
UNION ALL
SELECT
p.id_employee,
p.id_manager,
t.level + 1 AS level
FROM
(
SELECT
id_employee,
id_manager
FROM
people
) p
JOIN tree t ON p.manager_id = t.employee_id
)
SELECT *
FROM
tree;
现在,由于我要担任高层领导00001
,因此我将吸引组织中的所有人。但是,如果我在层次结构中间的某人的最后一行添加WHERE id_manager =
子句,我将只获得他们的直接报告。我想检索该经理下的所有直接报告,还希望检索那些经理下的报告。
是否有一种方法可以修改此构建/修改此查询以维护整个层次结构,但还可以查询它以标识中间的某个人,其所有子级以及相对于顶部的相对级别级老板?
谢谢!
答案 0 :(得分:1)
编辑:正如您在下面评论的那样,事实证明您的问题是我无法理解的。
您可能已经了解,递归CTE分为两部分。
WITH RECURSIVE MyCTE AS (
<Start of the recursion/loop>
UNION
<Step from level N to level N+1/N-1>
)
我们将:
Postgresql仅允许1个递归CTE(对于其他DBMS不确定),因此我们将需要一起执行2和3。我们只需要多加注意,就可以使查询以多个起点(id_manager IN (...)
)开头
WITH RECURSIVE tree(id_root_manager, id_direct_manager, id_employee, level) AS (
SELECT id_manager,
id_manager,
id_employee,
UNNEST(ARRAY[0,1]) /* level > 0: go to the bottom, level <= 0: go to the top of the hierarchy */
FROM people
WHERE id_manager IN ('00555')
UNION ALL
SELECT id_root_manager,
id_manager,
p.id_employee,
CASE WHEN level <= 0 THEN level-1 ELSE level+1 END
FROM people p
JOIN tree t ON (level > 0 AND p.id_manager = t.id_employee) OR (level <= 0 AND t.id_direct_manager = p.id_employee)
)
SELECT id_root_manager, id_direct_manager, id_employee, level - (SELECT MIN(level) FROM tree WHERE id_root_manager = h.id_root_manager) AS level
FROM tree h
WHERE level > 0
ORDER BY id_root_manager, level
如果您对“根”管理器不感兴趣,则可以通过将最终选择更改为以下方式来避免重复:
SELECT DISTINCT id_direct_manager, id_employee, level - (SELECT MIN(level) FROM tree WHERE id_root_manager = h.id_root_manager) AS level
FROM tree h
WHERE level > 0
ORDER BY level