分层查询 - 选择过滤员工及其邻居列表中的领导者(不是行)

时间:2016-03-16 22:33:19

标签: sql oracle hierarchical-data

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

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;

所以它返回正确答案,但我需要将LPADed名称显示为邻居列,如我在示例中所示。

1 个答案:

答案 0 :(得分:1)

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