I have an employee table, with the following data.
For a particular manager, i want to get the list of all employees, following the hierarchy of the manager.
id name manager
1 John 6
2 Gill 7
3 Ben 2
4 Roy 8
5 Lenin 6
6 Nancy 7
7 Sam 0
8 Dolly 3
For example, i have to get the employees under manager Sam(7). As you can see, Sam does not have any manager, but he is the manager for employees Gill and Nancy, who are the managers for employees Ben and John, Lenin respectively.
So i ran a query like this:
select * from employee where manager=7;
I get the result as 2 rows, Gill and Nancy.
But now, i also want to show the employees Ben and John, Lenin in the output, as they both are under the managers Gill and Nancy, who are under Sam.
How can i structure the query to show the employees hierarchically for a manager? In other words, how can i show all Gill, Nancy, Ben, John and Lenin under the manager Sam ?
Adding a IN subquery to your WHERE clause will handle that. For example:
SELECT * FROM employee WHERE manager = 7 OR manager IN (SELECT id FROM employee WHERE manager = 7)
For a better visuality you can also use this query:
select e1.name, e2.name, e3.name
from employee e1
left join employee e2 on e1.id = e2.manager
left join employee e3 on e2.id = e3.manager
where e2.manager = 7
whereas you have to add another left join for each hierarchy. That is a downside on the one hand, on the other hand it's easier to handle than in Sean's answer.
On the pro side you get an output like this:
name name1 name2
---------------------------------
Sam Gill Ben
Sam Nancy John
Sam Nancy Lenin
which is much more eye friendly and you can easily put it in an even more eye friendly form via PHP or something.
Related
I am still a rookie and learning SQL and I am stuck with two things That I can not do
-how to Display name of employees and names of their managers but they are on same table and column
-Find the names of the employees whose manager is “Salah Mohamed”
I know I can do it with inner join but it gets strange results when I try it.
Thanks in advance.
Department Table:
ID Name MGR_ID Branch no.
101 HR 80021 1
102 Technical support 80010 2
103 Marketing 80077 3
104 Logistics 78804 4
105 Engineering 56651 5
Emp Table:
ID Name dept_id
52213 Salah Mohamed 105
56651 Amr Saker 105
75515 Nahed Yousef 104
76605 Nour Waheed 102
78804 Amr Akl 104
80010 Ahmed Kamal 102
80021 Ahmed Attia 101
80045 Mona Ahmed 103
80065 Hesham Hamdy 101
80077 Lina Emad 103
You need to use inner join for entire solution and case .. when expression specially for the manager row as follows:
SELECT emp.NAME employee_name,
Case when emp.id <> mgr.id then mgr.NAME end as manager_name
FROM emp JOIN department d ON d.id = emp.dept_id
JOIN emp mgr ON d.mgr_id = mgr.id
This should solve it. Here you first join the employee table to department table to get the IDs of the manager. Then you join the department table to employee table again on manager id to get the names of the manager. Then you can put your manager name condition in where. Hope it helps.
Edit:
SELECT emp1.NAME employee_name,
mng.NAME manager_name
FROM emp emp1
JOIN department d
ON d.id = emp1.dept_id
JOIN emp mng
ON d.mgr_id = mng.id
where mng.NAME='Salah Mohamed'
I am attempting something very similar to last example (Using GROUP BY) on this page:
https://thecodedeveloper.com/mysql-count-function/
Referring to the following table of data:
id name salary department
1 Tom 4000 Technology
2 Sam 6000 Sales
3 Bob 3000 Technology
4 Alan 8000 Technology
5 Jack 12000 Marketing
The following query:
SELECT department, COUNT(*) AS "Number of employees"
FROM employees
GROUP BY department;
Will produce the following output:
department Number of employees
Marketing 1
Sales 1
Technology 3
Except I want to see the number of employees in each department as well as every user in the table.
So I want the output to look like this:
id name salary department employees per department
1 Tom 4000 Technology 3
2 Sam 6000 Sales 1
3 Bob 3000 Technology 3
4 Alan 8000 Technology 3
5 Jack 12000 Marketing 1
I have managed to achieve what I want using a second query to test every result from the first query but it is extremely slow and I am convinced that there is a faster way to do it in a single query.
That's a window count. In MySQL 8.0:
select e.*, count(*) over(partition by d.department) as number_of_employees
from employees e
In earlier versions, an alternative uses a correlated subquery:
select e.*,
(select count(*) from employees e1 where e1.department = e.department) as number_of_employees
from employees e
I have created a hypothetical scenario with some dummy data. Below are 3 basic tables and I'm looking to write a query to find what property/properties Mary has viewed.
In this scenario Mary has viewed 1 property a flat in Glasgow.
Table 1: Client
=====================
ID Name
=====================
5 Tom
6 Mary
7 John
Table 2: Property
=====================
ID CITY TYPE
=====================
14 Aberdeen House
16 Glasgow Flat
21 Glasgow House
94 London Flat
Table 3: Viewing
========================
Client Property Date
========================
5 14 01-12-2016
5 21 08-12-2016
6 16 10-10-2016
Definitely use inner joins for this, a quick example of this could be
SELECT c.Name, p.Type, p.City, v.Date
FROM Viewing v
JOIN Client c ON v.client = c.ID
JOIN Property p ON v.property = p.ID
WHERE c.Name = 'Mary'
That should show you who view what and when. I've used aliases on the table names just to keep it neat.
I have two tables
Employees
id employee_name JobTitle
---------------------------
1 John CEO
2 Ely MANAGER
3 Marcus MANAGER
4 Steve CEO
5 Fritz ASSISTANT
6 Orly ANALYST
7 Carlo ANALYST
7 Lee MANAGER
JobTitle Filter
filter_id JobTitle_keyword
---------------------------
1 CEO
2 MANAGER
Is it posible to use JobTitle_keyword as the filtering keyword?
so if I run the query... the result would be like this.
id employee_name JobTitle
---------------------------
1 John CEO
2 Ely MANAGER
3 Marcus MANAGER
4 Steve CEO
7 Lee MANAGER
Yes, you can do this in MySQL by using join.
SELECT t1.*
FROM Employees t1
JOIN JobTitleFilter t2
ON t1.jobtitle = t2.jobtitle_keyword
Check it working in this SQL fiddle.
You need to join the tables:-
SELECT emp.*
FROM Employees emp
INNER JOIN JobTitleFilter Job
ON emp.JobTitle = Job.JobTitle_Keyword
OR
Select emp.id,emp.employee_name,emp.JobTitle
FROM Employees as emp,JobTitle as Job
Where emp.JobTitle= Job.JobTitle_Keyword
SQL FIDDLE
try out this..
SELECT id,employee_name,JobTitle
FROM Employees e
INNER JOIN JobTitleFilter j ON e.JobTitle = j.JobTitle_Keyword
or you can also try this one..
SELECT id,employee_name,JobTitle
FROM Employees e
where e.JobTitle in (Select JobTitle_Keyword from JobTitleFilter)
SQL FIDDLE
I have an employees table, which has all the information about employees, including the manager_id, for example:
id name manager_id
1 Joe 5
2 Mary 5
3 Bill 5
4 Jane 6
5 Matt 6
6 Walt 7
I would like to get a list of people, and for each one all their direct reports. Is it possible to create a query to give me the following output:
Employee Direct Reports
Joe
Mary
Bill
Jane
Matt Joe, Bill, Mary
Walt Jane, Matt
This way:
SELECT s.name AS employee, group_concat( e.name )
FROM employees s
LEFT OUTER JOIN employees e ON s.id = e.manager_id
GROUP BY s.id
You have to join the table with itself. And you need to use left join, so that you get the employees who don't manage anyone.