Easiest way to find IsManager in SQL - sql

Simple structure table of employees
Employee Manager
Joe Smith Jon Smith
Jon Smith Pete Stevens
Pete Stevens NULL
Jared Scho Pete Stevens
....
Im just trying to return some results but I want an indicator on whether the person is a manager or not so the result should be:
Employee Manager IsAManager
Joe Smith Jon Smith 0
Jon Smith Pete Stevens 1
Pete Stevens NULL 1
Jared Scho Pete Stevens 0
The result set is showing that Joe Smith and Jared Scho are not managers...
So If I had a simple SQL Query
SELECT
Employee,
Manager,
As IsAManager --tried to do a case statement here....
FROM
Employee
I tried to do a case statement something to this effect:
SELECT CASE ISNULL(COUNT(*), 0) > 0 THEN 1 ELSE 0 END FROM Employee WHERE Manager = Employee
Not sure how to word it :)

Hopefully this is just a demo example not your real table structure.
SELECT Employee,
Manager,
CASE
WHEN EXISTS(SELECT *
FROM Employee e2
WHERE e2.Manager = e1.Employee) THEN 1
ELSE 0
END As IsAManager
FROM Employee e1
For details of how SQL Server processes EXISTS Subqueries in CASE Expressions see this article.

To determine whether an employee is a manager, you need to match the Employee's ID (in this case, the name) against the list of Manager IDs (in this case the Manager column). If you find a match, the employee is a manager. If you don't find a match, the employee is not a manager.
You can do this with a LEFT OUTER JOIN as shown here:
SELECT DISTINCT
E.Employee,
E.Manager,
CASE WHEN M.Employee IS NULL THEN 0 ELSE 1 END As IsAManager
FROM
Employee E LEFT OUTER JOIN Employee M
ON E.Employee = M.Manager
Please note the following:
You did not specify the SQL product you're using, so I tried to make the solution general. I'm guessing from your attempt to use ISNULL that it's SQL Server, but this solution should work in any product that supports CASE.
Your method of storing manager status has one problem, which is that you cannot represent a manager with no employees (you derive the manager status from the existence of the employee-manager relationship). If you want to be able to store manager status separately from the employee-manager relationship then CREATE TABLE Managers (Employee. . . PRIMARY KEY). This will make the code necessary to get back manager status a little easier to write as well.

Related

Compute number of direct report for each employee in the organization (aggregation)

FYI I use Redshift SQL.
I have a database that looks roughly like the one below (the database has multiple columns that I'll abstract away for simplicity).
This table is a representation of the hierarchical tree within my organization.
employee manager
-------- -------
daniel louis
matt martha
martha kim
laura matt
michael martha
...
As you can see, matt appears in two distinct records, one as the employee and the other as laura's manager. Martha appears in three records, one as an employee and in two other as manager.
I'd like to find a way to compute the number of direct reports each employee has. A conditional count in which the criteria would be where employee = manager, perhaps?
I guess I could find this information using a subquery and then join it back but I was wondering if there was a more "elegant" way to do this making use of window functions maybe.
The expected output for the table above would be:
employee manager direct_reports
-------- ------- --------------
daniel louis 0
matt martha 1
martha kim 2
laura matt 0
michael martha 0
...
I would approach this with a correlated subquery:
select
t.employee,
t.manager,
(select count(*) from mytable t1 where t1.manager = t.employee) direct_reports
from mytable t
This should be a quite efficient method, especially with an index on (employee, manager).
Use a left join and aggregation:
select em.employee, em.manager, count(ew.employee)
from employees em left join
employees ew
on ew.manager = em.employee
group by em.employee, em.manager;

Cursor vs standard SQL

I have seen the following question approached to be solved as a cursor although I seen efficiency doing it as a multiple join. How can I solve this via a cursor and should i bother doing so as im extracting it via excel?
RecordID EmpID FirstName LastName HiredDate FiredDate
1111 1 John Flanagan 1/02/2013 1/02/2014
2222 1 Michael Richards 1/01/2014 1/02/2015
3333 3 Peter Johnson 1/08/2014 1/07/2016
4444 3 Jim Crow 1/09/2014 1/02/2017
5555 3 Own Wilson 1/010/2014 1/03/2015
Here's my attempt with SQL initially.
select EmpID, count(RecordID), HiredDate
from Employer
group by EmpID
order by DESC.
Need to write a query that returns each individual employer and for each row include the max employees that were hired by the company and the date of the last hire.
I was asked to write it as a cursor as they wanted to extract the above data line by line from excel.
If EmpId is employer id you are almost there:
SELECT EmpID, COUNT(RecordID), MAX(HiredDate)
FROM Employer
GROUP BY EmpID
ORDER BY EmpID ASC
This will get you the output you require, but I'm not sure what you wanted to order by...I've assumed EmpId.
I've also assumed SQL Server.

SQL Newbie Stuck on Manager Flag Field Logic

This is my first month of being a Data Analyst, and I can't seem to find an answer that is specific enough to my problem here to help. I am having trouble getting this manager flag field to work and I think I'm getting confused by the joins.
The goal is to match the EMPLIDs of JOB_VW A to see if they exist in the Supervisor_ID column of Supervisor_VW K. Supervisor_VW K has ALL employees in the company (including supervisors) in the K.EMPLID column. Someone can be in both the supervisor ID column and EMPL column at the same time, but in different rows. The SUP ID is the EMPL ID of someone in a manager position.
For example:
Supervisor_VW K
EMPL ID EMPL NAME SUP ID SUP NAME
1 Smith, John 2 William, Mark
5 Jarvis, John 2 William, Mark
2 William, Mark 4 Rover, Spot
The results I am getting are as such
QUERY RESULTS
EMPLID EMPL NAME MANAGER FLAG
2 William, Mark Y
2 William, Mark Y
4 Rover, Spot Y
1 Smith, John N
5 Jarvis, John N
My current code is as follows:
SELECT CASE WHEN K.Supervisor_Id IS NULL THEN
'N'
ELSE
'Y'
END AS "ManagerFlag".....
FROM (SELECT K.*
FROM SUPERVISOR_VW K, JOB_VW A
WHERE K.SUPERVISOR_ID (+) = A.EMPLID
AND EXISTS (SELECT K1.EMPLID, K1.SUPERVISOR_ID
FROM SUPERVISOR_VW K1
WHERE K1.EMPLID IN K1.Supervisor_Id)
) K
So it seems that I am getting duplicate supervisor rows for every single employee that they supervise. If they supervise only one person, I get a singular row. If they supervise 20, I get 20 duplicate rows of that supervisor. HOWEVER, their employee that they supervise shows up in the table without issue and is properly labeled as N, no duplicates.
If anyone could help, please do! I appreciate you reading through my work, let me know if more info is required.
The usual way to achieve the desired result is like this:
select emplid, emplname,
case when emplid in (select supid from supervisor_vw) then 'Y'
else 'N' end as managerflag
from supervisor_vw;

SQL Query to find out all managers and any manager that reports directly to that manager

I have a table demo_snap with columns of employee and supervisor information.
I want to find out all managers and any manager that reports directly to that manager including him/herself.
The query is really confusing me :(
The query which will give the employee and supervisor information is :
Select
employee_number,
first_name e_first_name,
last_name e_last_name,
supervisor_employee_number,
supervisor_first_name,
supervisor_last_name
from demo
Can anybody help me out to mould this query in such a way to find all managers and any manager that reports directly to that manager including him/herself
Sample output of the above query is :
e_number f_name l_name supervisor_e_number s_first_name s_last_name
1 John Smith 2 Adam juan
4 Shree Lekha 2 Adam juan
6 Hema Malini 3 Shruti Hasan
7 Gauri Mikha 1 John Smith
The desired output i want that is i want to create a query such that the following employees are fetched :-
active managers- 2,3 and managers that reports to the active manager-1
The query I have created is :- but this is not giving the desied output
WITH mgr_temp
AS (SELECT person_id mgr_person_id,
employee_number mgr_num,
first_name mgr_name,
supervisor_number mgr_sup
FROM demo mgr
)
SELECT mgrs.mgr_num HISL_ID,
delegs.mgr_num DELEGATE_HISL_ID,
mgrs.mgr_name emp_name,
delegs.mgr_name sup_name
FROM mgr_temp mgrs, mgr_temp delegs
WHERE mgrs.mgr_sup = delegs.mgr_sup
AND mgrs.mgr_num <> delegs.mgr_num

MS Access: Selecting the first item according to a rank

Imagine I have a query called QueryA that returns stuff like this:
Employee Description Rank
John Happy 1
John Depressed 3
James Happy 1
James Confused 2
Mark Depressed 3
I am trying to make a query that grabs the Employee and the Description, but only one description -- the one with the best "rank." (the lower the rank the better). I sort QueryA by Employee then by Rank (descending).
So I'd want my new query QueryB to show that John as Happy, James as Happy, and Mark as Depressed.
However I try selecting Employee and then First of Description and it doesn't always work.
I'm not able to check this for Access, but it should work fine. Check my SQL Fiddle
select
r.employee, d.description
from
table1 as d
inner join (select min(rank) as rank, employee
from
table1
group by employee) r on d.rank = r.rank
and d.employee = r.employee