2015-06-20 17 views
1

考虑以下表如何在自循环表中导航?

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); 

其是自循环表即每个雇员拥有管理器,除了根。

我想运行在此表下面的查询:

找到比他们的管理者更多的薪金所有的员工?


附:

只有一个根在结构

考虑下面的查询

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; 

它为员工表中的每个员工从下到上创建一个子树,但我不知道如何浏览以获得期望的结果!

+1

首先让我们知道你已经尝试过什么? –

+0

经理可以在他上面有经理吗?之后的下一个,等等?在这种情况下,你希望查询返回什么? (就像Deepak说的,告诉我们你到目前为止) – sstan

+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

0

这应该做的工作。如果您不想在列表中显示“根”,请删除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) 
+0

上述SQL代码“找到所有比他们的经理工资更高的员工”是错误的! 请注意,每个经理都有一个层级的管理者,直到根,即如果A是B的经理,C是A的经理,我们也可以说C是B的经理。假设根是最低工资,所以结果集应该控制除root之外的所有人! –