如何在自循环表中导航?

时间:2015-06-20 03:44:14

标签: sql oracle hierarchical-data hierarchical-query

考虑下表

create table EMPLOYEE
(
  empno    NUMBER not null,
  ename    VARCHAR2(100),
  salary   NUMBER,
  hiredate DATE,
  manager  NUMBER
);

alter table EMPLOYEE add constraint PK_EMP primary key (EMPNO);

alter table EMPLOYEE 
   add constraint FK_MGR foreign key (MANAGER)
      references EMPLOYEE (EMPNO);

这是一个自循环表,即每个员工都有一个经理,除了根。

我想在此表上运行以下查询:

  

找到所有员工的薪水都超过他们的经理?

P.S。

结构中只有一个根

考虑以下查询

SELECT LPAD(emp.ename, (LEVEL-1)*5 + LENGTH(emp.ename), ' ') AS "Hierarchy"
    FROM employee emp
    START WITH emp.manager IS NULL
    CONNECT BY manager = PRIOR empno;

结果将是这样的:

Alice
    Alex
    Abbey
Sarah
Jack
    Bill
    Jacob
    Valencia
Bob
    Babak
...

我做了以下查询

SELECT LPAD(emp.ename, (LEVEL-1)*5 + LENGTH(emp.ename), ' ') AS "Hierarchy"
  FROM employee emp
    START WITH empno IN (SELECT empno FROM employee)
    CONNECT BY PRIOR manager = empno; 

从底部到顶部为员工表中的每个员工创建一个子树,但我不知道如何导航以获得所需的结果!

2 个答案:

答案 0 :(得分:1)

这是一种方法

with fullemployee (empno, ename, salary, key)
as
(
  select A.empno, A.ename, A.salary, A.empno || '.' from 
      employee A
  where A.manager is null
  union all
  select C.empno, C.ename, C.salary, D.key || '.' || C.empno from 
      employee C
      inner join fullemployee D on C.manager = D.empno
)
select E.ename, F.ename as manager from fullemployee E
inner join fullemployee F on E.key like F.key || '%' and E.key <> F.key
where E.salary > F.salary

或等效

with fullemployee (empno, ename, salary, key)
as
(
   SELECT empno, ename, salary, SYS_CONNECT_BY_PATH(empno, '.') || '.'
   FROM employee
   START WITH manager is null
   CONNECT BY PRIOR empno = manager
)
select E.ename, F.ename as manager from fullemployee E
inner join fullemployee F on E.key like F.key || '%' and E.key <> F.key
where E.salary > F.salary

SQL小提琴 - http://sqlfiddle.com/#!4/37f4ae/35

答案 1 :(得分:0)

这应该做的工作。如果您不希望列表中包含“root”,请删除or条件。

select e.empno, e.ename, e.salary from employee e
    inner join employee mgr on mgr.empno = e.manager
where e.salary > mgr.salary
or (e.manager = mgr.empno)