I have a table called Employees
ID
Full Name
Employee Type
Employment Rate
Manager ID
143
Sam Smith
Full Time
Wage
146
144
Jay Reddy
Part Time
Wage
146
145
Nick Young
Full Time
Wage
146
146
Trevor Simm
Full Time
Salary
147
147
Justin Peters
Part Time
Salary
147
148
Lisa Howard
Full Time
Salary
140
149
Nicky West
Full Time
Salary
140
150
Gemma Yu
Full Time
Wage
146
151
Sally Zhang
Part Time
Salary
140
152
James Hillary
Full Time
Wage
146
153
Nikita Shaw
Full Time
Wage
146
I want to run a query where it should return Wage employees. I want to also include those Wage employees' managers in the query so it should return something like this:
ID
Full Name
Employee Type
Employment Rate
Manager ID
143
Sam Smith
Full Time
Wage
146
144
Jay Reddy
Part Time
Wage
146
145
Nick Young
Full Time
Wage
146
146
Trevor Simm
Full Time
Salary
147
147
Justin Peters
Part Time
Salary
147
150
Gemma Yu
Full Time
Wage
146
152
James Hillary
Full Time
Wage
146
153
Nikita Shaw
Full Time
Wage
146
Querying the Wage employees is easy enough though wondering if you can help me with the query so that it also includes their managers in the list:
Select * From Employees
Where [Employment Rate] = 'Wage'
If you use a CTE to determine the relevant employees you can then union on a query to obtain their managers e.g.
WITH cte AS (
SELECT *
FROM Employees
WHERE [Employment Rate] = 'Wage'
)
SELECT * FROM cte
UNION ALL
SELECT * FROM Employees WHERE Id IN (SELECT [Manager ID] FROM cte);
You could use a sub query like like this
Select *
From Employees
Where [Employment Rate] = 'Wage'
or ID in (SELECT [Manager ID] FROM Employees Where [Employment Rate] = 'Wage')
You could also use a UNION statement -- which I like better because I would add a new column in there showing the source of the data -- in my experience you always want this when working with data in this way:
SELECT 'Worker' as SOURCE,
ID, [Full Name], [Employee Type], [Employment Rate], [Manager ID]
FROM Employees
WHERE [Employment Rate] = 'Wage'
UNION ALL
SELECT 'Manager' as SOURCE,
ID, [Full Name], [Employee Type], [Employment Rate], [Manager ID]
FROM Employees
WHERE ID IN (SELECT [Manager ID] FROM Employees Where [Employment Rate] = 'Wage')
Note -- if a employee has a wage rate they will appear twice with this query, but not with the first one.
Related
I have the following table Employee storing any updates made on an employee:
EmployeeId DepartmentId Status From To
44 30 Recruited 01/01/2017 06/03/2017
44 56 IN 07/03/2017 07/03/2018
44 67 IN 06/05/2018 06/09/2018
44 33 IN 07/09/2018 02/02/2019
44 33 OUT 03/02/2019 31/12/2019
44 45 Recruited 01/02/2020 03/02/2020
44 45 IN 04/02/2020 NULL
I want to count how many times each employee has changed his department knowing that the employee life cycle is like below : Recuited - IN - OUT
and the employees that left the company then went back to it like in this example.
I'm not sure what "Recruited", "In" and "Out" have to do with this. If each row represents a period of time when an employee was in a department, then use lag() to measure changes:
select employeeId, count(*)
from (select t.*,
lag(departmentId) over (partition by employeeId order by from_date) as prev_departmentId
from t
) t
where prev_departmentId is null or prev_departmentId <> departmentId
group by employeeId;
SQL> select employeeid, fname, salary, supervisor from employee;
EMPLOYEEID FNAME SALARY SUPERVISOR
---------- --------------- ---------- ----------
111 Heng 265000
246 Ananda 150000 111
231 Nagapan 85000 246
123 Vellu 105000 111
443 Fatimah 80000 111
433 Amin 66500 443
323 Kamuingat 76500 443
200 Jing 24500 135
135 Hong 45000 111
322 Derek 75000 123
128 Dong 38000 135
248 Fatt 30000 135
I want the supervisor column view as the supervisor name. the name already exists in the fname. How to make the supervisor name view based on the id in the employeeid column?
You probably want something like this:
select e.employeeid, e.fname, e.salary, s.fname
from employee e join employee s on (e.supervisor = s.employeeid)
You are joining the employee table to itself using the supervisor column as the id column. If that doesn't make sense, look up joins in the docs.
I think you need to self join using outer join otherwise the first record where the supervisor is null will be omitted from the result.
So I guess following is the query which you should try:
select e.employeeid, e.fname, e.salary, s.fname
from employee e left join employee s on (e.supervisor = s.employeeid)
Note that I have done left join.
Cheers!!
I was asked during an interview about this SQL question.
Given Employee table
LastName DepartmentID
Rafferty 31
Jones 33
Heisenberg 33
Robinson 34
Smith 34
Daniel 34
Williams NULL
and Department table
DepartmentID DepartmentName
31 Sales
33 Engineering
34 Clerical
35 Marketing
How could I find ALL of the employees who is at the same department as 'Robinson'? (through a generic way)
Is join (inner join) something that he wanted me to do?
You can use IN:
select *
from employee
where departmentId in (
select departmentId
from employee
where LastName = 'Robinson'
);
Using JOIN:
select e.*
from employee e
join (
select distinct departmentId
from employee
where LastName = 'Robinson'
) e2 on e1.departmentId = e2.departmentId;
I have two tables :
One for employees data Employee
Another for employee vacations balance VacBal
Now i want to get the current vacation balance for each employee,considering if the emp_num = 0 then it's a general balance for all employees not for specific employee
If Employee table Sample data like that :
emp_num name
546 john
134 Ramy
and
VacBal like that
emp_num bal_num bal_date
546 1 5-5-2015
546 2 6-5-2015
134 1 7-5-2015
0 3 2-2-2015
0 4 6-1-2015
I want result set like this :
emp_num name SUM(bal_num)
546 john 10 --->3+7
134 Ramy 8 --->1+7
How to do this ?
You can use a correlated sub-query to SUM:
select e.emp_num, e.name, (select sum(vb.bal_num) from VacBal vb
where vb.emp_num in (e.emp_num,0))
from Employee e
SELECT e.emp_num,
name,
Sum(bal_num) + (SELECT Sum(bal_num)
FROM vacbal vb
WHERE emp_num = 0)
FROM employee e
inner join vacbal v on e.emp_num=v.emp_num
GROUP BY e.emp_num,
name
I have a table of my sales agents' sales, by quarter:
Agent Quarter Sales
----------------------------
Alex Andersen 2011Q1 358
Alex Andersen 2011Q2 289
Alex Andersen 2011Q3 27
Alex Andersen 2011Q4 2965
Brian Blogg 2010Q3 277
Brian Blogg 2010Q4 123
Brian Blogg 2011Q1 783
Brian Blogg 2011Q2 0
Christy Cliff 2011Q2 777
Christy Cliff 2011Q3 273
Christy Cliff 2011Q4 111
Christy Cliff 2012Q1 901
What's the simplest, most efficient query for getting each agent's earliest quarter and the sales for that quarter?
It's easy to find out "What is each agent's first quarter?":
SELECT agent, min(quarter) FROM salestable GROUP BY agent
But this doesn't include the sales figures, so I thought I'd do a join:
SELECT agent, sales
FROM salestable s1
JOIN
(
SELECT agent AS e, MIN(quarter) AS q
FROM salestable
GROUP by employee
) AS q1 ON q1.e=s1.agent AND q1.mq=s1.quarter
But this is unacceptably slow on my data set. If I could use a cursor, it would only take one pass through the table, but using a query it seems to require a join. Is that right?
Try this variation and see if it's any better:
WITH cteRowNum AS (
SELECT agent, quarter, sales,
ROW_NUMBER() OVER (PARTITION BY agent ORDER BY quarter) AS RowNum
FROM salestable
)
SELECT agent, quarter, sales
FROM cteRowNum
WHERE RowNum = 1;