Как получить сотрудников с их руководителями
Это то, что я хочу выходной, чтобы выглядеть так:
Employee Emp# Manager Mgr#
BLAKE 7698 KING 7839
CLARK 7782 KING 7839
JONES 7566 KING 7839
MARTIN 7654 BLAKE 7698
ALLEN 7499 BLAKE 7698
TURNER 7844 BLAKE 7698
JAMES 7900 BLAKE 7698
WARD 7521 BLAKE 7698
FORD 7902 JONES 7566
SMITH 7369 FORD 7902
SCOTT 7788 JONES 7566
ADAMS 7876 SCOTT 7788
MILLER 7934 CLARK 7782
вот что я получил:
SQL> SELECT ename, empno, (SELECT ename FROM EMP WHERE empno = mgr)AS MANAGER, mgr from emp order by empno;
ENAME EMPNO MANAGER MGR
---------- ---------- ---------- ----------
SMITH 7369 7902
ALLEN 7499 7698
WARD 7521 7698
JONES 7566 7839
MARTIN 7654 7698
BLAKE 7698 7839
CLARK 7782 7839
SCOTT 7788 7566
KING 7839
TURNER 7844 7698
ADAMS 7876 7788
ENAME EMPNO MANAGER MGR
---------- ---------- ---------- ----------
JAMES 7900 7698
FORD 7902 7566
MILLER 7934 7782
Я не могу найти, почему поле менеджер пустое.
вот:
SQL> select empno, ename, job,deptno, mgr from emp;
EMPNO ENAME JOB DEPTNO MGR
---------- ---------- --------- ---------- ----------
7839 KING PRESIDENT 10
7698 BLAKE MANAGER 30 7839
7782 CLARK MANAGER 10 7839
7566 JONES MANAGER 20 7839
7654 MARTIN SALESMAN 30 7698
7499 ALLEN SALESMAN 30 7698
7844 TURNER SALESMAN 30 7698
7900 JAMES CLERK 30 7698
7521 WARD SALESMAN 30 7698
7902 FORD ANALYST 20 7566
7369 SMITH CLERK 20 7902
EMPNO ENAME JOB DEPTNO MGR
---------- ---------- --------- ---------- ----------
7788 SCOTT ANALYST 20 7566
7876 ADAMS CLERK 20 7788
7934 MILLER CLERK 10 7782
выбрано 14 строк.
5 ответов
Это классический self-join, попробуйте следующее:
SELECT e.ename, e.empno, m.ename as manager, e.mgr
FROM
emp e, emp m
WHERE e.mgr = m.empno
и если вы хотите включить президента, у которого нет менеджера, то вместо внутренний присоединиться к использовать внешний присоединяйтесь к синтаксису Oracle:
SELECT e.ename, e.empno, m.ename as manager, e.mgr
FROM
emp e, emp m
WHERE e.mgr = m.empno(+)
или в синтаксисе ANSI SQL:
SELECT e.ename, e.empno, m.ename as manager, e.mgr
FROM
emp e
LEFT OUTER JOIN emp m
ON e.mgr = m.empno
(SELECT ename FROM EMP WHERE empno = mgr)
в EMP нет записей, которые соответствуют этим критериям.
вам нужно самостоятельно присоединиться, чтобы получить это отношение.
SELECT e.ename AS Employee, e.empno, m.ename AS Manager, m.empno
FROM EMP AS e LEFT OUTER JOIN EMP AS m
ON e.mgr =m.empno;
EDIT:
выбранный вами ответ не будет перечислять вашего президента, потому что это внутреннее соединение. Я думаю, вы вернетесь, когда обнаружите, что ваш результат не то, что требуется (я подозреваю) домашнее задание. Вот фактический тестовый пример:
> select * from emp;
empno | ename | job | deptno | mgr
-------+-------+-----------+--------+------
7839 | king | president | 10 |
7698 | blake | manager | 30 | 7839
(2 rows)
> SELECT e.ename employee, e.empno, m.ename manager, m.empno
FROM emp AS e LEFT OUTER JOIN emp AS m
ON e.mgr =m.empno;
employee | empno | manager | empno
----------+-------+---------+-------
king | 7839 | |
blake | 7698 | king | 7839
(2 rows)
разница в том, что внешнее соединение возвращает все строки. Внутреннее соединение произведет следующее:
> SELECT e.ename, e.empno, m.ename as manager, e.mgr
FROM emp e, emp m
WHERE e.mgr = m.empno;
ename | empno | manager | mgr
-------+-------+---------+------
blake | 7698 | king | 7839
(1 row)
возможно, ваш подзапрос (SELECT ename FROM EMP WHERE empno = mgr)
думает, дайте мне записи сотрудников, которые являются их собственными менеджерами! (т. е., где empno строки совпадает с mgr то же самое row.)
вы думали, возможно, переписать это, чтобы использовать внутреннее (само) соединение? (Я спрашиваю, потому что я даже не уверен, будет ли следующее работать или нет.)
SELECT t1.ename, t1.empno, t2.ename as MANAGER, t1.mgr
from emp as t1
inner join emp t2 ON t1.mgr = t2.empno
order by t1.empno;
ПОПРОБУЙТЕ ЭТО
SELECT E.ename,E.empno,ISNULL(E.ename,'NO MANAGER') AS MANAGER FROM emp e
INNER JOIN emp M
ON M.empno=E.empno
Instaed подзапроса использовать self join
вы могли бы просто изменить свой запрос:
SELECT ename, empno, (SELECT ename FROM EMP WHERE empno = e.mgr)AS MANAGER, mgr
from emp e
order by empno;
Это сообщило бы движку, что для внутренней таблицы emp, empno должен быть сопоставлен с столбцом mgr из внешней таблицы.