Home > Enterprise >  List the "manager's name" and the "number of employees" in that manager
List the "manager's name" and the "number of employees" in that manager

Time:06-02

"List the "manager's name" and the "number of employees" in that manager's department" is the requested query for my class. I cannot embed pictures yet so I will do my best to have them formatted properly on here

Here is some data from the employees table:

EMPNO---ENAME----JOB----------MGR----SAL---- DEPTNO

7839--- KING-----PRESIDENT---     ---5000-----10

7698----BLAKE----MANAGER-----7839----2850-----30

7782----CLARK----MANAGER-----7839----2450-----10

7566----JONES----MANAGER-----7839----2975-----20

7654----MARTIN---SALESMAN----7698----1250-----30

7499----ALLEN----SALESMAN----7698----1600-----30

7900----TURNER---SALESMAN----7698----1500-----30

7521----JAMES----CLERK-------7698----950------30

7902----WARD-----SALESMAN----7698----1250-----30

7902----FORD-----ANAYLYST----7566----3000-----20

the code I currently have is:

SELECT A.ENAME, COUNT(*)

FROM EMP A

JOIN EMP B

ON A.DEPTNO = B.DEPTNO

GROUP BY A.ENAME;

This code seems to give me all employees and the number of employees in their department. From the question, I believe that I only need the 3 employees with the with job = 'MANAGER'. Unfortunely, I cannot figure out how to accomplish this and have the correct count of employees in their dept. Any direction or help would be appreciated.

CodePudding user response:

SELECT A.ENAME, COUNT(*) 
FROM EMP A 
   JOIN EMP B ON A.DEPTNO = B.DEPTNO 
WHERE A.JOB = 'MANAGER'
GROUP BY A.ENAME;

Please correct me if I'm wrong.

CodePudding user response:

That's the good, old Scott's EMP table. If presented as a tree, it looks like this:

SQL> select lpad(' ', 2 * level) || ename hierarchy
  2  from emp
  3  connect by prior empno = mgr
  4  start with mgr is null;

HIERARCHY
--------------------------------------------------------------------------------
  KING
    JONES
      SCOTT
        ADAMS
      FORD
        SMITH
    BLAKE
      ALLEN
      WARD
      MARTIN
      TURNER
      JAMES
    CLARK
      MILLER

14 rows selected.

SQL>

Apparently,

  • King is Jones', Blake's and Clark's manager
  • Jones is manager to Scott and Ford
  • Scott is manager to Adams
  • Ford is manager to Smith
  • etc.

Self-join then returns

SQL> select m.ename, count(*)
  2  from emp e join emp m on m.empno = e.mgr
  3  group by m.ename
  4  order by count(*) desc;

ENAME        COUNT(*)
---------- ----------
BLAKE               5
KING                3
JONES               2
SCOTT               1
FORD                1
CLARK               1

6 rows selected.

SQL>

On the other hand, if you want to specify MANAGERS only along with some data from the DEPT table, you'll again need self-join (of the EMP table), but this time it'll be OUTER JOIN because department "Operations" doesn't have any employees (nor a manager):

SQL> select d.dname, e.ename, count(e.rowid) cnt
  2  from dept d left join emp e on e.deptno = d.deptno
  3                             and e.job = 'MANAGER'
  4              left join emp m on e.deptno = m.deptno
  5  group by d.dname, e.ename;

DNAME          ENAME             CNT
-------------- ---------- ----------
RESEARCH       JONES               5
SALES          BLAKE               6
ACCOUNTING     CLARK               3
OPERATIONS                         0

SQL>

CodePudding user response:

You can use a hierarchical query (which will avoid having to self-join the table).

If you want all to count all the people in the department who do not have the job of MANAGER then:

SELECT MAX(PRIOR ename) AS mgr_name,
       COUNT(*) AS num_employees
FROM   emp
WHERE  LEVEL = 2
START WITH job = 'MANAGER'
CONNECT BY NOCYCLE
       PRIOR deptno =  deptno
AND    PRIOR empno  <> empno
GROUP BY PRIOR empno

Which outputs:

MGR_NAME NUM_EMPLOYEES
JONES 4
CLARK 2
BLAKE 5

If you want to count all the people who are in the same department as the manager and are managed by that manager then:

SELECT MAX(PRIOR ename) AS mgr_name,
       COUNT(*) AS num_employees
FROM   emp
WHERE  LEVEL = 2
START WITH job = 'MANAGER'
CONNECT BY PRIOR empno = mgr
GROUP   BY PRIOR empno

Which, for the Scott schema, outputs:

MGR_NAME NUM_EMPLOYEES
JONES 2
CLARK 1
BLAKE 5

If you wanted to do it without hierarchical queries then you can use:

SELECT MAX(m.ename) AS mgr_name,
       COUNT(*) AS num_employees
FROM   emp m
       INNER JOIN emp e
       ON (   m.deptno =  e.deptno
          AND m.empno  <> e.empno )
WHERE  m.job = 'MANAGER'
GROUP BY m.empno

and

SELECT MAX(m.ename) AS mgr_name,
       COUNT(*) AS num_employees
FROM   emp m
       INNER JOIN emp e
       ON (   m.deptno = e.deptno
          AND m.empno  = e.mgr )
WHERE  m.job = 'MANAGER'
GROUP BY m.empno

db<>fiddle here

  • Related