2015-06-20 2 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); 

, который является самостоятельными петельными таблицы, т.е. каждого сотрудника имеет менеджер, кроме корня.

Я хочу, чтобы выполнить следующий запрос на этой таблице:

найти все сотрудники, имеющие больше зарплату, чем их руководители?


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; 

, который делает поддерево для каждого сотрудника в таблице сотрудников снизу вверх, но я не знаю, как перемещаться, чтобы достичь желаемого результата!

+1

первых, дайте нам знать, что вы пробовали ?? –

+0

может у менеджера есть менеджер на нем? А следующий после этого и т. Д.? Что вы ожидаете, когда запрос вернется в этом случае? (И, как сказал Дипак, покажите нам, что у вас есть) – 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, если вы не хотите, чтобы «root» был в вашем списке.

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. , предположим, что корень - это человек с минимальная зарплата, поэтому набор результатов должен охватывать всех, кроме корня! –

Смежные вопросы