Output the names of bosses who manage multiple employees - sql

I have a database of personnel which has an EMPLOYEE_ID, EMPLOYEE_NAME and BOSS_ID. I'm trying to display the employee_name of all bosses who manage 3 or more people. The following query provides me with all the right BOSS_ID's.
SELECT BOSS_ID FROM PERSONNEL
GROUP BY BOSS_ID
HAVING COUNT(BOSS_ID) >= 3
However I wish to only display the EMPLOYEE_NAME of the bosses, not their BOSS_ID. I tried this, but it produced no names at all.
SELECT EMPLOYEE_NAME FROM PERSONNEL
GROUP BY EMPLOYEE_NAME
HAVING COUNT(BOSS_ID) >= 3
Any help would be greatly appreciated.

To get the Manager Name your can do Self Join.
In the below example to get the Manager name you need to get it from P2 Reference.
SELECT DISTINCT P2.EMPLOYEE_NAME AS ManagerName
FROM PERSONNEL P1
JOIN PERSONNEL P2 ON P1.BOSS_ID = P2.EMPLOYEE_ID
GROUP BY P2.EMPLOYEE_NAME
HAVING COUNT(P1.BOSS_ID) >= 3

You can do a JOIN on the same table to obtain the boss's name.
SELECT p.Employee_name, b.Employee_name as "Boss Name"
FROM personnel p
INNER JOIN personnel b ON b.Employee_ID = p.Boss_ID

you can try using a subquery.
SELECT Employee_name
FROM PERSONNEL
where BOSS_ID IN (
SELECT BOSS_ID FROM PERSONNEL
GROUP BY BOSS_ID
HAVING COUNT(BOSS_ID) >= 3
)
db fiddle

Related

query to find number of employees under each manager

I have an Employee table with columns : Id, Name, Manager_Name
I need to list: count of employees under each manager.
How to form a simple sql query for achieving result?
Note: There may be two managers with same name.
Table:-
create table employee_test (Id int , Name VARCHAR(100), Manager_Name varchar(100));
Input:
ID NAME MANAGER_NAME
-- ------ ------------
1 deep hari
2 mitra hari
3 hari kishan
4 kirti kishan
5 kishan amit
6 jumeet hari
7 fareed deep
8 stuti kishore
My Attempt:-
SELECT m.Name as ManagerName, count(e.Name) as employeesCount
FROM employee_test e
INNER JOIN employee_test m ON e.Manager_Name = m.Name
group by m.Name
My Output:-
MANAGERNAME EMPLOYEESCOUNT
----------- --------------
kishan 2
hari 3
deep 1
But it does not take care of other manager's employee count?
UPDATE:- Question was little unclear to me too as being exactly asked by an interviewer, request to close the question.
I imagine you want this:
select Manager_Name, count(Name)
from Employee
group by Manager_Name
In addition to the response by MJH, if there can be two managers with the same name, there needs to be a way to differentiate them.
Say for instance you have the following (in SQL Server):
create table Employee (Name VARCHAR(100), Manager_Id INT)
create table Managers (Id INT, Name VARCHAR(100))
SELECT d.Manager_Name, d.employeesCount
FROM(
SELECT m.Id, m.Name as Manager_Name, count(e.Name) as employeesCount
FROM Employee e
INNER JOIN Managers m ON e.Manager_Id = m.Id
group by Id, m.Name
) d

does anyone know how to list the empid and the name of all supervisors if supervisors are in employee table too?

I have a table that contains empid, name, salary, hiredate, position and supervisor (which includes empid, not the name). How do I list the empid and name of all supervisors?
The output has to have to columns supervisor (and a list of their empid) and their names. This is the create statement used to create the Employee table:
/* Create table Employee */
IF OBJECT_ID('Employee', 'U') IS NOT NULL
DROP TABLE Employee
GO
CREATE TABLE Employee (
emp_id NCHAR(5),
name NVARCHAR(20),
position NVARCHAR(20),
hire_date DATETIME,
salary MONEY,
bcode NCHAR(3),
supervisor NCHAR(5)
)
I have tried a variety of statements using having statement and count but they don't seem to work.
select emp_id, name from employee where position='manager';
I tried this but it doesn't work. Anyone smart that knows how to do it?
You will have to join the table back on itself:
select a.name, a.position, a.hiredate, a.salary, a.supervisorid,
isnull(b.name, '') as SupervisorName
from EmployeeTable a
left join EmployeeTable b
on a.SupservisorID=b.ID
The left join will make sure that the employees who do not have supervisors are returned, and isnull(b.name, '<NONE>') can be used if you would like to have something other than NULL as a value in those cases.
SELECT e.empid ,ISNULL(b.name, 'No supervisor') SupervisorName
FROM employee e LEFT JOIN employee b
ON e.supervisorid = b.empid
Inner join will leave out the people who do not have a supervisor , Use left join to get all the employees
If you want supervisors only, you just need to select rows whose emp_id values are found in the supervisor column:
SELECT
SupervisorID = emp_id,
SupervisorName = name
FROM dbo.Employee
WHERE emp_id IN (SELECT supervisor FROM dbo.Employee)
;

SQL subquery Total/Count

I am trying to write a query that lists the name of a manager and the number of people they manage.
In the Manager table we have the managers name and id.
In the Employee table we have the employees name, id and managerID.
I don't understand how to get the count of the employees that a manager manages.
SELECT COUNT(e.EmpID), m.ManagerID
FROM Employee e
INNER JOIN Manager m
ON e.ManagerID= m.ManagerID
GROUP BY m.ManagerID
SELECT m.Name, COUNT(e.id) AS NumberOfEmployeesManaged
FROM Manager m INNER JOIN Employee e ON m.id = e.managerID
GROUP BY m.Name
That should do it I think, just a simple count of the employee ids after joining the manager and employee tables, grouped on manager name.
SELECT count(emp.empid), mgr.managerid
FROM Employee emp
INNER JOIN Manager mgr ON emp.managerid=mgr.managerid
GROUP BY mgr.managerid;
I don't know if you can use the COUNT aggregator in a JOIN. But you can run 2 queries. One would select the manager's name & id. The 2nd would look like this:
$id = the manager's id
SELECT COUNT(*) FROM Employee WHERE managerID=$id
Alternately, you could not use COUNT and run a query like this:
SELECT id FROM Employee WHERE managerID=$id
Then the # of resulting rows would be the count of employees managed by the manager.

How to get the duplicate names of employees who have multiple employee numbers

I'm using Oracle 10g.
If i have the following duplicate rows (Same Employee with two Employee numbers):
Employee_No Employee_Name ID_NO
----------------------------------------------
0002345 John Debb 100345642
0030988 John Debb 100345642
----------------------------------------------
i want to get the result as:
Employee_No_1 Employee_No_2 Employee Name ID_NO
----------------------------------------------------------------
0002345 0030988 John Debb 100345642
----------------------------------------------------------------
Is it possible to be done in SQL? or it needs PL/SQL? and what would the query be?
SELECT MIN(Employee_no), MAX(employee_no), Employee_name, id_no
FROM Employee
GROUP BY Employee_name, id_no
HAVING MIN(employee_no) <> MAX(employee_no)
I don't do Oracle, but I think this is pretty generic syntax that should work.
Not quite in the format requested, but this will handle the case where there could be more than just 2 duplicates.
SELECT e.Employee_No, e.Employee_Name, e.ID_NO
FROM (SELECT Employee_Name, ID_NO
FROM Employee
GROUP BY Employee_Name, ID_NO
HAVING COUNT(*) > 1) q
INNER JOIN Employee e
ON q.Employee_Name = e.Employee_Name
AND q.ID_NO = e.ID_NO
ORDER BY e.Employee_Name, e.ID_NO, e.Employee_No
Query is as below,
select e1.employee_no, e2.employee_no, e1.employee_name, e1.id_no
from employee e1
join employee e2
on e1.id_no = e2.id_no
where e1.employee_no < e2.employee_no

New Sql query solution

person_id | manager_id | name |
| | |
-------------------------------
I have to display name of every person with manager name.
Yes its complete table. Thats all I have.
This one should give you all employees that have a manager, with employee_name and manager_name. Replace your_table by your table name.
If you want to get all persons, also that without manager, replace the JOIN by a LEFT JOIN. This would return NULL as manager_name for all persons without manager_id.
SELECT t1.name employee_name, t2.name manager_name
FROM [your_table] t1
JOIN [your_table] t2 ON ( t1.manager_id = t2.person_id )
Which SQL dialect? Here's some TSQL, but I'm vague to the actual question ("every person with manager name"); if you mean "given a manager name, list the people (reports)", then:
SELECT peon.[person_id], peon.[name]
FROM [thetable] mgr
INNER JOIN [thetable] peon
ON peon.manager_id = mgr.[person_id]
WHERE mgr.[name] = #name
ORDER BY peon.[name]
If you mean "list the people, along with their manager's name", then:
SELECT peon.[person_id], peon.[name], mgr.[name] AS [manager]
FROM [thetable] peon
LEFT OUTER JOIN [thetable] mgr
ON mgr.[person_id] = peon.manager_id
ORDER BY peon.[name]
SELECT person.name, manager.name
FROM table person, table manager
WHERE person.manager_id = manager.person_id