How to find all the employees under one manager using a subquery? SQL - sql

does anyone know how to create a subquery to find all the employees under one manager? For example if I want to find someone that works on susan jones how would I create the query?
Manager Table:
Employee ID Manager_ID Name Title
1 NULL James Smith CEO
2 1 Ron Johnson Sales Manager
3 2 Fred Hobbs Sales Person
4 1 Susan Jones Support Manager

select employeename,managerid
from manager
where manager_id is not null
group by employeename ,manager_id

Well, supposing the table for employees is simply named Employee and its key is named 'Employee_ID' (like in the Manger table), then you just need to use a simple Join:
SELECT e.* FROM Employee AS e JOIN Manger AS m ON e.Employee_ID=m.Employee_ID WHERE m.Name='Susan Jones'

Related

SQL join manager from same table onto a row with their employees

To start, here's a dummy table I've made to show the data I'm working with:
employee
title
division
email
Boss Person
boss
o
bp#email
John Smith
supervisor
a
jos#email
Jane Smith
supervisor
b
jas#email
Leo Messi
employee
a
lm#email
Amanda Kessel
employee
a
ak#email
Derek Jeter
employee
b
dj#email
I want to end up with the following info:
employee
title
division
email
supervisor_name
supervisor_email
Boss Person
boss
o
bp#email
NULL
NULL
John Smith
supervisor
a
jos#email
Boss Person
bp#email
Jane Smith
supervisor
b
jas#email
Boss Person
bp#email
Leo Messi
employee
a
lm#email
John Smith
jos#email
Amanda Kessel
employee
a
ak#email
John Smith
jos#email
Derek Jeter
employee
b
dj#email
Jane Smith
jas#email
I've looked through and tried documentation at:
https://www.sqltutorial.org/sql-self-join/
SQL Server : LEFT JOIN EMPLOYEE MANAGER relationship
One of the big differences here is I don't have any employee or manager id column to work with.
If you're a supervisor for a division, ie John Smith is a supervisor in division a, then you manage all the employees in division a. Meanwhile, all the supervisors answer to the boss in division o, while the boss answers to no one.
Here is the best code I've tried so far:
select e.*, b.employee as supervisor, b.email as supervisor_email
from employees e, employees b
where b.division = e.division
and
b.title like '%supervisor%'
This got me close, it returned:
employee
title
division
email
supervisor_name
supervisor_email
John Smith
supervisor
a
jos#email
John Smith
jos#email
Jane Smith
supervisor
b
jas#email
Jane Smith
jas#email
Leo Messi
employee
a
lm#email
John Smith
jos#email
Amanda Kessel
employee
a
ak#email
John Smith
jos#email
Derek Jeter
employee
b
dj#email
Jane Smith
jas#email
So, it got the employee info right, but left out the Boss record and placed the supervisors as their own supervisor. I think I need some kind of case or if statement here, but I'm not sure.
Please let me know if this makes sense or if any further clarification is needed.
You could try using a LEFT JOIN and work with two conditions:
when division is the same and we're dealing with the relationship employee < supervisor
when the relationship is supervisor < boss
Here's how I did it:
SELECT t1.*,
t2.employee,
t2.email
FROM tab t1
LEFT JOIN tab t2
ON (t1.division = t2.division AND
t2.title = 'supervisor' AND
t1.title = 'employee')
OR (t2.title = 'boss' AND
t1.title = 'supervisor')
You'll find an SQL fiddle here.
If you want to update the current table (if columns are available), you can do the following (more or less the same as #lemon) :
UPDATE testing t1 JOIN testing t2 ON t2.`division`=t1.division OR t2.division="o" SET
t1.supervisor_name=t2.`employee`, t1.supervisor_email=t2.email
WHERE (CASE
WHEN t1.`title`="employee" THEN t2.title="supervisor"
WHEN t1.`title`="supervisor" THEN t2.title="boss"
END);
SELECT * FROM testing;

Need help fetching data from DB2

S.no
emp_id
emp_name
Dept
1
100
John
Sales
2
100
John
Accounts
3
200
Mike
Sales
4
300
Mark
Sales
5
300
Mark
Accounts
6
400
Tom
Sales
I need to pull all the emp_id who are linked ONLY to Sales Dept and ignore the ones that are in both Sales and Accounts. I am using DB2 z/os. Any suggestions would be helpful? Thanks in advance.
An anti-join will produce the result you want.
For example:
select s.*
from employee s
left join employee a on a.emp_id = s.emp_id and a.dept = 'Accounts'
where s.dept = 'Sales' and a.emp_id is null
For good performance you can try adding the index:
create index ix1 on employee (emp_id, dept);

SQL query that will add a column returning a value when two other columns match (similar to vlookup in excel)

I have an employee table that lists all employees and the ID of their manager. The Manager ID refers back to the employee id in this table. I would like to add another column that returns the name of the manager since no one knows their ID numbers.
Current table is basically:
ID Name ManagerID
31 John Smith 10
32 Barb Jones 10
33 Craig Adams 32
I would like to add another column that looks up looks up the manager ID in the ID field and returns the assocaited name like below:
ID Name ManagerID ManagerName
31 John Smith 10 Ted Fish
32 Barb Jones 10 Ted Fish
33 Craig Adams 32 Barb Jones
You can use self-join here.
select e.ID, e.Name, m.ManagerID, e.Name as ManagerName
from employee e
inner join employee m
on e.ID = m.ManagerID;

How to get employees listed under their manager? SQL

I have a database:
Staff Name
1 Blake
2 Jake
Mgr Emp
2 6
2 8
3 5
4 7
Is it possible to search up all employees but list them under the manager?
Select all:
Staff Name Mgr
1 Blake null
2 Jake null
6 Scott 2
8 Jack 2
3 Clark null
5 Martin 3
4 Smith null
7 Scott 4
And is there a way to look up the team when a staff is searched?
Search: "Scott"
Returns:
Staff Name Mgr
2 Jake null
6 Scott 2
8 Jack 2
http://rextester.com/OAREI7219 is solution
CREATE TABLE Managers (
MgrID int ,
EmpID int
)
CREATE TABLE Staff (
EmpID int,
name nvarchar(50)
)
Query is ;
SELECT
s.EmpID AS Staff,
s.name AS Name,
m.MgrID
FROM Staff s LEFT JOIN Managers m ON s.EmpID = m.EmpID ;
GO
Assuming that you have:
a table "staff" with all the people in the company. For clarity I will rename the "Staff" column to "id".
a many to many table "staff_manager" to link employees with their managers. For clarity I will rename the "Mgr" column to "manager_id" and the "Emp" to "employee_id".
all tables named lowercase and plural.
You may do:
SELECT employees.id, employees.name, managers.id, managers.name
FROM staff as employees
LEFT JOIN employee_managers ON (employee_managers.employee_id = employees.id)
LEFT JOIN staff as managers ON (managers.id = employee_managers.manager_id)
for the second query you add a where clause to the above query:
WHERE managers.name = "Scott" OR employees.name = "Scott"
NOTE: If you may change the model of your database, I would suggest to
set a UNIQUE constrain on the employee_id of the staff_managers table,
so that one employee can have ONLY ONE manager.
To get All Employees with their managers. Try
Select staff.Id,Staff.name,managers.mgr
From staff left join managers on staf.id=managers.emp
To search about employee and get his team with the manager also. Try
— Search: 'scott'
Select staff.Id,Staff.name,managers.mgr
From staff left join managers on staf.id=managers.emp
Where managers.mgr =(select t.mgr from managers as t where t.emp='scott')
Union all
Select staff.Id,Staff.name,managers.mgr
From managers left join staff on staf.id=managers.mgr
Where managers.emp='scott'

SQL Reports - sorting an column based on the date mentioned in another column adjacent to it

It would be great if someone can help me out. I am new to SQL.
This is what my table data is
table name: emp
e_no e_name e_jobrole position promotion_date
1 Robin Sales CEO 01/01/2012
1 Robin Sales CFO 20/01/2010
2 Jackman Sales - S1 EMP 01/04/2009
4 Sheldon Marketing MGR 15/08/2012
4 Sheldon Marketing SNRMGR 01/01/2011
4 Sheldon Marketing MGR 01/01/2011
3 Arnold Marketing CEO 09/09/2009
5 Emmy Marketing SNRMGR 08/08/2008
6 Penny Admin SNRMGR 05/05/2012
6 Penny Admin MGR 09/09/2007
By ordering through the date these guys promoted, I need to capture the previous position held by the employee and adjacent to that current position. Is this possible ?
Below is what I required as Output
e_no e_name e_job prev_pos curr_pos promotion_date
1 Robin Sales CFO CEO 01/01/2012
2 Jackman Sales - S1 Not Available EMP 01/04/2009
4 Sheldon Marketing MGR MGR 15/08/2012
3 Arnold Marketing Not Available CEO 09/09/2009
5 Emmy Marketing Not Available SNRMGR 08/08/2008
6 Penny Admin MGR SNRMGR 05/05/2012
EDIT: I seem to have been proven wrong just seconds after posting :P
I don't think you can do that in one query (except using a complicated stored procedure).
How about getting the data into an application (in Java, or whatever you would like) and then parse the data from the oldest data, and keeping track of the "previous position" of each employee. Then, whenever you get to one that you've already got a "previous position" for you can insert that into the table, and update the "previous position" (and if you haven't seen her before, set the "previous position" to null/"none"/""/etc).
Would that be useful, or would it have to be all done on the DB?
Something like this should work. The combination of WHERE and HAVING may need some adjustment.
select
c.e_no,
c.e_name,
c.e_job,
p.position as prev_position,
c.position as curr_position,
c.promotion_date
from
emp c
inner join
emp p
on
c.e_no=p.e_no
group by
c.e_no,
c.e_name,
c.e_job,
p.position as prev_position,
c.position as curr_position,
where
p.promotion_date < c.promotion_date
having
max(p.promotion_date),
max(c.promotion_date)