SQL subquery Total/Count - sql

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.

Related

INNER JOIN and Count POSTGRESQL

I am learning postgresql and Inner join I have following table.
Employee
Id Name DepartmentId
1 John S. 1
2 Smith P. 1
3 Anil K. 2
Department
Department
Id Name
1 HR
2 Admin
I want to query to return the Department Name and numbers of employee in each department.
SELECT Department.name , COUNT(Employee.id) FROM Department INNER JOIN Employee ON Department.Id = Employee.DepartmentId Group BY Employee.department_id;
I dont know what I did wrong as I am new to database Query.
When involving all rows or major parts of the "many" table, it's typically faster to aggregate first and join later. Certainly the case here, since we are after counts for "each department", and there is no WHERE clause at all.
SELECT d.name, COALESCE(e.ct, 0) AS nr_employees
FROM department d
LEFT JOIN (
SELECT department_id AS id, count(*) AS ct
FROM employee
GROUP BY department_id
) e USING (id);
Also made it a LEFT [OUTER] JOIN, to keep departments without any employees in the result. And COALESCE to report 0 employees instead of NULL in that case.
Related, with more explanation:
Query with LEFT JOIN not returning rows for count of 0
Your original query would work too, after fixing the GROUP BY clause:
SELECT department.name, COUNT(employee.id)
FROM department
INNER JOIN employee ON department.id = employee.department_id
Group BY department.id; --!
That's assuming department.id is the PRIMARY KEY of the table, in which case it covers all columns of that table, including department.name. And you may want LEFT JOIN like above.
Aside: Consider legal, lower-case names exclusively in Postgres. See:
Are PostgreSQL column names case-sensitive?

How to get hive query for one to many relation with in a table

I have a employee hive table with columns name and department. where 1 employee can belongs to multiple departments.
name, department
xxx,finance
xxx,hr
xxx,transport
xxx,sale
yyy,finance
yyy,hr
yyy,transport
zzz,finace
zzz,hr
zzz,transport
zzz,sale
I need to know distinct employee name who does not belongs to "sale" department.
As of hive 0.13
Select name from employee
where employee.name not in
(select name from employee where department = 'sale')
group by name;
Hopefully names are unique across employees.
You could write a subquery to pull all names that are in sales. Then join that query's results back to your table.
select
results.name,
results.department
from
(select e.name
from employee e
where e.department='sale' group by e.name) invalid_names
right join
(select
e.name,
e.department
from employee e) results
on invalid_names.name = results.name
where invalid_names.name is null;
I'd imagine there is a better way to do this, but this should work :)

Using output of one select query as input for another

I have an employee table which includes ManagerID as a foreign key. To get the currently logged ManagerId on Employees, I use a statement like -
SELECT MgrId FROM Employees WHERE EmpId=#EmpId
#EmpId is currently Logged on Employees.
I need to get the currently logged on employees manager and the manager's manager in one statement. This involves using the output of the above statement as input of another select statement. I am unsure how to do this. Any help is much appreciated.
Assuming your Employee ID field is named Id
SELECT e.Id [EmployeeId], e.MgrId [ManagerId], m.MgrId [ManagerManagerId]
FROM Employees e
LEFT JOIN Employees m ON e.MgrId = m.Id
WHERE e.EmpId=#EmpId

How to get result in following scenario

I have table
EMP(id int primary key, name varchar2(15), mgrID int).
Now this table contain all employees(including worker and manager) in company. mgrID column contain id of employee to whom they are reporting.
I want to list the name of worker who is not manager along with their name of manager.
What to do for such query.
I tried nested select query as follows:
select name, (select name from EMP where mgerID is NULL)
as Manager from EMP;
Will this query give proper result?
You could use a self-join:
SELECT e.name AS name, m.name AS manager_name
FROM emp e
JOIN emp m ON e.mgrid = m.id
Your query should fail because you sub-query is uncorrelated and will return multiple results if you have multiple top-level managers.
select name
, (select name from EMP b where b.ID = a.mgerID ) as Manager
from EMP a;
I think the self-join is the more canonical solution, but you should understand the correlated subquery as well as it has many application.

Get employees who worked in more than one department with SQL query

I'm trying to figure out a query which shows the names of the employees who worked in more than 2 departments along with their wage and contact details. I have two tables employees and department. Both of these having the EmployeeName field. I know we have to use the Count function but don't really know how to create the query.
here the tablename and Fields:
Employee (employeeName, wage, contactNo)
Department (employeeName, departmentNo, hours, startDate)
You SQL query would be the following
SELECT e.employeeName, count(departmentNo) FROM Employee e
INNER JOIN Department d ON e.employeeName=d.employeeName
GROUP BY e.employeeName
HAVING COUNT(departmentNo)>2
you can use following query:
SELECT e.employeeName, count(d.departmentname)
FROM Employee e, Department d
where e.deptid=d.deptid
GROUP BY e.employeeName
HAVING COUNT(e.deptid)>=2