Using output of one select query as input for another - sql

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

Related

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.

Replacing a table value with the previous expression in oracle

Ok so I am having the following scenario
I have a table called employees and have to replaced the last names for some of the people there under the following conditions:
1-The last name must be replaced only to those employees who work on Oxford.
2-Their new last name is going to be the last name of the person that has their employee number -1 ( for instance employee#173 should have now employee#172 last name instead)
This is how I started the query:
select last_name,num_emp
from employees
where num_emp in(
select e.num_emp
from employees
join departments using(num_dept)
join office using(id_office)
where city='Oxford')
And I did a second query to make sure which values were going to replace which
Select last_name,num_emp
from employees
where num_emp in(
select (e.num_emp-1)
from employees
join departments using(num_dept)
join office using(id_office)
where city='Oxford')
Now I thought I could do this and make the code work... but it didn't:
update employees
set last_name=(select last_name
from employees
where num_emp in(
select (e.num_emp-1)
from employees
join departments using(num_dept)
join office using(id_office)
where city='Oxford')
Got error saying unexpected end of SQL command...
So I thought on making a change because I believed having too many values on the set was not the point and here is how I did it for last time:
update employees
set last_name=(select last_name
from employees)
where num_emp =(
select (e.num_emp-1)
from employees
join departments using(num_dept)
join office using(id_office)
where city='Oxford')
Got an error that says is missing right parenthesis, which I know it does not express whaat the issue is. I know I am missing something and part of the sintaxis is wrong as well as I may need to créate another table and add those values so that they get saved there and I can compare them with the original ones, but at this point I am totally blocked and can't discover what is the mistake I am doing. Please help me I'd really apprecciate it!
You are getting confused with what to update and what to update with in your statements.
Here is what to update. I use IN clauses to make it plain. An EXISTS clause would also be appropriate.
update employees
set last_name = ...
where num_dept in
(
select num_dept
from departments
where id_office in
(
select id_office
from office
where city = 'Oxford'
)
);
And here is what to update with:
set last_name =
(
select last_name
from employees prev_employee
where prev_employee.num_emp = employee.num_emp - 1
)
You should use the analytical lag function, then you also fill in gaps if for example employee 172 doesn't exist and you have to put the name of employee 171 in 173.
Your select should be something like this
with new_emp as
(select last_name,lag(last_name, 1, 0) over (order by num_emp) as new_last_name, num_emp
from employees)
select *
from new_emp
where num_emp in(
select e.num_emp
from employees e
join departments using(num_dept)
join office using(id_office)
where city='Oxford');
This select will give you the original last name, new last name, employee number.
Then afterwards your update should be this:
update employees x
set last_name = (with new_emp as
(select last_name,lag(last_name, 1, 0) over (order by num_emp) as new_last_name, num_emp
from employees)
select new_last_name
from new_emp ne
where ne.num_emp = x.num_emp)
where x.num_emp in(
select e.num_emp
from employees e
join departments using(num_dept)
join office using(id_office)
where city='Oxford');

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

SQL subquery Total/Count

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.

Deriving a column's data from a matching column in SQL

So I have a table that has, employee number, employee name, supervisor number.
I want to run a query that will retrieve employee name, employee number, supervisor name and supervisor number. Only one employee doesn't have a supervisor meaning it will have to display nulls. How would I do this? I'm using Oracle SQL Plus. My attempts haven't worked at all! Any help would be much appreciated.
SELECT ename Employee, empno Emp#, super Manager#
FROM emp;
That gets me three of the columns but to be honest I don't even know where to start to get the supervisors names.
It's for university, but I'm studying for a test it's not for an assignment so no cheating happening here :).
The following should work, and give you nulls if the employee has no supervisor:
SELECT empGrunt.ename Employee
, empGrunt.empno EmpNum
, empSuper.ename SupervisorName
, empSuper.empno SupervisorName
FROM emp empGrunt LEFT OUTER JOIN emp empSuper
ON empGrunt.super = empSuper.empno
Assuming that SupervisorNumber is a foreign key relationship back to the Employee table (where it's the EmployeeNumber of the supervisor's record), then you need to use an outer join.
What you need in this case is a left join:
select
e.EmployeeName,
e.EmployeeNumber,
s.EmployeeName as SupervisorName
from Employee e
left join Employee s on s.EmployeeNumber = e.SupervisorNumber