分层查询 - 在相邻列(而不是行)中选择过滤后的员工及其领导

Hierarchical query - selecting filtered employees and their leaders in neighbour-colums (not rows)

所以我需要使用 f.e 显示层次结构而不是行。 LPAD() 但在列中。因此,例如,如果我有这种关系

Employees (name VARCHAR(15), function VARCHAR(15), #leader)

职能从1到6,如何向所有领导介绍职能5或6的员工?我的意思是,如果我们使用 LPAD 将其呈现在行中并从较低级别开始,它将如下所示:

name 
Mike -->(function 5)
   Bruce
       Lee
Lea  -->(function 6)
   Fred
       Mike
          Bruce

我需要它看起来像这样:

name     function    leader1(lowest level)  leader2   leader3(highest level in this example)
Mike        5              Bruce              Lee
Lea         6              Fred               Mike         Bruce

当然应该过滤掉 Mike、Lea 等具有功能 5 或 6,而 Bruce、Lee、Fred 等哪个功能并不重要

好的,为了更方便地帮助我,我创建了一个包含查询数据的数据库示例,我使用 LPAD

在行中显示结果
CREATE TABLE Employees (
name VARCHAR2(15) CONSTRAINT name_pk PRIMARY KEY,
function NUMBER(2) CONSTRAINT function_nn NOT NULL,
leader VARCHAR2(15) CONSTRAINT leader_fk REFERENCES Employees(name)
);


alter table
Employees
DISABLE constraint
leader_fk;


INSERT INTO Employees VALUES ('Mike', 5, 'Lee');
INSERT INTO Employees VALUES ('Bruce', 5, 'Lee');
INSERT INTO Employees VALUES ('Lee', 3, NULL);
INSERT INTO Employees VALUES ('Lea', 6, 'Fred');
INSERT INTO Employees VALUES ('Fred', 1, 'Mike');


alter table
Employees
ENABLE constraint
leader_fk;

WITH 
hierarchia (poziom, name, function, leader)
AS (
SELECT 0 poziom, name, function, leader
FROM Employees
WHERE function IN (5, 6) 
UNION ALL 
SELECT
h.poziom + 1, e.name, e.function, e.leader
FROM hierarchia h, Employees e
WHERE h.leader = e.name
)
SEARCH DEPTH FIRST BY name SET order_by_name
SELECT LPAD(' ', 2*poziom) || name, function
FROM hierarchia
ORDER BY order_by_name;

所以它 returns 正确答案,但我需要将 LPAD 名称显示为我在示例中显示的邻居列。

WITH 
hierarchia (root, poziom, name, function, leader)
AS (
SELECT  name, 0 poziom, name, function, leader
FROM Employees
WHERE function IN (5, 6) 
UNION ALL 
SELECT h.root,
h.poziom + 1, e.name, e.function, e.leader
FROM hierarchia h, Employees e
WHERE h.leader = e.name
)
select Root, function, Leader1, Leader2 , Leader3  from (
select root,  poziom, name from hierarchia )
pivot
(
 max(Name) 
 for poziom in (  1 as leader1, 2 as leader2, 3 as leader3) 
)  X
join Employees e
on e.Name = X.root 

PIVOT 函数会将您的行更改为列。

Root    Function    Leader1 Leader2 Leader3
Lea     6           Fred    Mike    Lee
Bruce   5           Lee     
Mike    5           Lee