Displaying supervisors who supervised 3 or more employees - mysql

Employee TABLE
ID Name Supervisor_ID
1 James NULL
2 Peter 1
3 Howard 1
4 Michele 2
5 Nicholas 2
6 Donald 2
7 Jackson 3
8 Anderson 3
9 Jeff 3
10 Will 3
I should get this at the end
ID Name Supervisor_Of_X_Employee
4 Peter 3
2 Howard 4
I tried doing
SELECT t1.employee_id
FROM employee t1
JOIN (SELECT DISTINCT supervisor_id FROM employee) t2
ON t1.employee_id = t2.supervisor_id;
Doesn't seem to produce what I want
Any ideas?
Thanks

You want to find the supervisor count so you group on the supervisor id like this
SELECT Supervisor_ID, count(*) as CNT
FROM employee
GROUP BY Supervisor_ID
add a HAVING COUNT(*) > 2 to get the ones that are 3 or more.
Oh... but you want the name too? then you have to join back to the table to get the name.
SELECT E.ID, E.Name, SUB.CNT
FROM (
SELECT Supervisor_ID, count(*) as CNT
FROM employee
GROUP BY Supervisor_ID
HAVING COUNT(*) > 2
) AS SUB
JOIN employee as E on E.ID = SUB.Supervisor_ID

SELECT Supervisor_id, COUNT(*) AS Supervisor_Of_X_Employee
FROM employee
GROUP BY Supervisor_id
if you need the name you'll have to do an inner join
SELECT employee_grouped.Supervisor_id, employee.Name, Supervisor_Of_X_Employee
FROM employee
INNER JOIN (
SELECT Supervisor_id, COUNT(*) AS Supervisor_Of_X_Employee
FROM employee
GROUP BY Supervisor_id
) employee_grouped ON employee.Id = employee_grouped.Supervisor_id

I would suggest using a self join approach with aggregation here:
SELECT
e1.Name,
COUNT(*) AS Supervisor_Of_X_Employee
FROM employee e1
INNER JOIN employee e2
ON e1.ID = e2.Supervisor_ID
GROUP BY
e1.Name
HAVING
COUNT(*) > 2;
Demo

Related

Query to list the departments that have more employees than a certain department

The database I have is:
emp(empno, ename, job , mgr, hiredate, sal, comm, deptno)
dept(deptno, dname, loc)
and I am trying to find out departments that have a number of employees more than the department “Operations”
the dept table:
------------------------------
deptno | dname | loc
------------------------------
10 | Accounting | New York
20 | Research | Dallas
30 | Sales | Chicago
40 | Operations | Boston
I have tried
SELECT `DNAME` FROM dept HAVING COUNT(*) > (
SELECT COUNT(*) AS Employees, `DNAME`
FROM emp INNER JOIN dept
ON emp.DEPTNO = dept.DEPTNO
WHERE dept.DEPTNO=40
GROUP BY DNAME)
But I keep getting an error:
#4078 - Illegal parameter data types bigint and row for operation '>'
You need sub-query :
SELECT COUNT(*) AS Employees, d.`DNAME`
FROM emp e INNER JOIN
dept d
ON e.DEPTNO = d.DEPTNO
GROUP BY d.`DNAME`
HAVING COUNT(*) > ( SELECT COUNT(*)
FROM emp AS e1
WHERE e1.DEPTNO = 40
)
having requires a group by clause. Also, the subquery should return just one column, and does not need to use table dept.
Consider:
select d.dname
from dept d
inner join emp e on e.deptno = d.deptno
group by d.dptno, d.dname
having count(*) > (select count(*) from emp e where e.deptno = 40)
Try this:
SELECT `DNAME` FROM dept GROUP BY `DNAME` HAVING COUNT(*) > (
SELECT COUNT(*) AS Employees, `DNAME`
FROM emp INNER JOIN dept
ON emp.DEPTNO = dept.DEPTNO
WHERE dept.DEPTNO=40)

sql query for a certain condition

I have a table like:
empId empSalary empDept
1 45000 IT
2 40000 IT
3 50000 SALES
4 60000 SALES
5 75000 IT
6 80000 IT
7 25000 OPS
8 30000 OPS
9 55000 MARKETING
10 60000 MARKETING
I have to write a query as:
select empId where empSalary > avg(empSalary) for each empDept
Kindly help.
Try this:
SELECT e.empId, e.empSalary, e.empDept
FROM employee e
INNER JOIN (SELECT e1.empDept, AVG(e1.empSalary) empSalary
FROM employee e1
GROUP BY e1.empDept
) a ON e.empDept = a.empDept AND e.empSalary > a.empSalary;
EDIT
SELECT e.empDept, COUNT(DISTINCT e.empid) noOfEmployees
FROM employee e
INNER JOIN (SELECT AVG(e1.empSalary) empSalary FROM employee e1) a ON e.empSalary > a.empSalary
GROUP BY e.empDept;
Could be something with a subquery, approximately as follows:
SELECT empID FROM TABLE t
WHERE empSalary > (SELECT AVG(empSalary) FROM TABLE WHERE empDept = t.empDept)
But can also be done with a JOIN that probably performs better:
SELECT empID FROM TABLE t
JOIN (SELECT empDept, AVG(empSalary) AS avgSalary FROM TABLE GROUP BY empDept) averages
ON t.empDept = averages.empDept
WHERE t.empSalary > averages.avgSalary
EDIT: the updated question calls for something slightly different, as per first comment below. Here's a count of how many employees are above the overall average salary, by department:
SELECT empDept, count(empID) FROM
(SELECT empID, empDept from TABLE
WHERE empSalary > (SELECT AVG(empSalary) FROM TABLE) aboveAverageEmployees
GROUP BY empDept

SELECT using GROUP BY and display the total with two tables

Having two tables
Department table
//Department
D# DNAME
-------------------
1 SALES
2 ACCOUNTING
3 GAMES
5 SPORTS
Project table
//Project
P# D#
-----------
1001 1
1002 3
1003 5
1004 5
When output display it should be something like:
Department Total Project
---------------------------
1 1
2 0
3 1
5 2
Currently my statement
SELECT D# FROM DEPARTMENT
WHERE (SELECT COUNT(*) FROM PROJECT WHERE DEPARTMENT.D# = PROJECT.D#);
but what should i display 0 if no any project in that D# ?
SELECT D.D#,
COUNT(p.P#)
FROM Department d
LEFT JOIN Project p
ON Project.D#=Department.D
GROUP BY d.D#;
Try This:
SELECT D# , CASE WHEN A.COUNT > 0 THEN D# ELSE 0 END AS TOTAL_PROJECT
FROM DEPARTMENT JOIN (SELECT D# , COUNT(*) FROM PROJECT GROUP BY PROJECT.D#) A ON
DEPARTMENT.D# = A.D#;
A simple left join with group by could achieve such requirement.
SELECT
DEPARTMENT.D#,
COUNT(PROJECT.P#) AS TotalProject
FROM DEPARTMENT
LEFT JOIN PROJECT ON DEPARTMENT.D# = PROJECT.D#
GROUP BY DEPARTMENT.D#
Check below query:
SELECT
D# as 'Dept_ID',count(P#) as 'Count'
from
department d
left join project p
on d.D#=p.D#
group by d.D#;

Update Duplicate column values based on Count in MySQl

I Have a Table like this
Employeeid Name CompanyID
1 Achal 1
2 Anil 1
3 Anil 1
4 Sachi 2
5 Anil 2
6 Sachi 1
7 Sachi 2
I want to update the names of the employee if multiple employees are there in a same company
My resultant table should be like this
Employeeid Name CompanyID
1 Achal 1
2 Anil(1) 1
3 Anil(2) 1
4 Sachi(1) 2
5 Anil 2
6 Sachi 1
7 Sachi(2) 2
My query is something like this
Update tblemplayee emp
join
(
select sname,count(*)
from tblemployee
group by sname,companyid
) innertable
on innertable.employeeid=emp.employeeid
set sname = concat(sname,'(', ,')') .
How can i change my query to get the result.
If you need to execute your query only once, you could use this query:
UPDATE
employees INNER JOIN (
SELECT e1.Employeeid, COUNT(e2.Employeeid) n
FROM
employees e1 INNER JOIN employees e2
ON e1.Name=e2.Name
AND e1.CompanyID=e2.CompanyID
AND e1.Employeeid>=e2.Employeeid
INNER JOIN (SELECT Name, CompanyID
FROM employees
GROUP BY Name, CompanyID
HAVING COUNT(*)>1) dup
ON e1.Name=dup.Name AND e1.CompanyID=dup.CompanyID
GROUP BY
e1.Employeeid, e1.Name) counts
ON employees.Employeeid = counts.Employeeid
SET
Name = CONCAT(Name, '(', counts.n, ')');
Please see fiddle here.

How to get records which does not have entry in 2nd table

for ex
department
id departmentname
1 x
2 y
3 z
employee
fkdepartmentid empname
1 john
1 sam
2 ram
3 hari
Here one empname can belong to any number of departments.
My requirement is get all the departments from department table where empname!=john (with a join).
I tried with the following query:
SELECT d.id FROM department d
INNER JOIN employee e ON d.id=e.fkdepartmentid
WHERE((e.empname<>'1')OR d.id IN (SELECT DISTINCT fkdepartmentid FROM employee WHERE fkdepartmentid NOT IN (SELECT DISTINCT fkdepartmentid FROM employee WHERE empname=sam)) ) GROUP BY d.id
However, the query is slow and failing in some scenarios.
the results should be 2 and 3. How can I achieve those results?
Here you go
SELECT * FROM department WHERE id IN( SELECT fkdepartmentid FROM employee WHERE empname !='john' GROUP BY fkdepartmentid )
If understand correctly you want to exclude department 1 because Jhon is an employer of that department. If it so you need to reverse the conditions.
Try
SELECT *
FROM department
WHERE id NOT IN
(
SELECT fkdepartmentid
FROM employee
WHERE empname = 'john'
GROUP BY fkdepartmentid
)
Output:
| ID | DEPARTMENTNAME |
-----------------------
| 2 | y |
| 3 | z |
Here is SQLFiddle demo
here is one which does not use nested queries:
SELECT t1.*
FROM department AS t1
LEFT JOIN employee AS t2
ON t2.deptid = t1.id AND t2.name IN ('john', 'rari')
WHERE t2.name IS NULL;
this lists all departments which does not have any employee with the name in list.