How to find levels of managers in self-referenced key - sql

So I have a table employees(ID, MaganerID)
My task is to find 2-nd level manager who is not getting any bonuses(another table)
I'm stuck here. Any advice what should I do next?
SELECT ID
FROM Employees
WHERE ID NOT IN (Select EmployeeID FROM Bonuses)
AND ID IN (Select LeaderID FROM Employees WHERE LeaderID IS NOT NULL)
AND ID NOT IN (Select ID FROM Employees WHERE ID <> LeaderID)

Well since you want a level 2 manager is much more simple:
SELECT DISTINCT E2.ID
FROM Employees E
INNER JOIN Employees E1 ON E1.ID = E.ManagerID
INNER JOIN Employees E2 ON E2.ID = E1.ManagerID
INNER JOIN Bonuses B ON B.EmployeeID = E2.ID AND B.Bonus = 0
You could also use the Recurse option using the WITH keyword if you are using TSQL. If you simply dont want to not exists on the other table just reverse the last bool check on the join.

Presumably by second-level manager you mean where their EmployeeID is somebody else's LeaderID, whose EmployeeID in turn is a third person's LeaderID?
I think currently you'll just get first level managers.
This should work... I've included your final WHERE statement, although you don't explain what that's for. Do you really want to exlude records where the ID is different to the LeaderID?
SELECT L2.ID
FROM Employees E
JOIN Employees L1 on E.LeaderID = L1.ID
JOIN Employees L2 on L1.LeaderID = L2.ID
WHERE L2.ID not in (SELECT EmployeeID from Bonuses)
AND L2.ID NOT IN (Select ID FROM Employees WHERE ID <> LeaderID)

Related

retrive sql query

SQL query to retrive the following condition. There are two cloumns one with user_id;s as primary keys and another tale as manager key. i want to retrive the query so that it displays manager key along with the user id's as manager 1, manager 2
Try this: you can achieve this using a self join
SELECT e1.name, e1.managerid, e2.name, e2.user_id
FROM Employee e1
INNER JOIN Employee e2
ON e1.managerid= e2.user_id
Try this, you can use the same approach for finding the heirarchy:
SELECT e1.name AS EmployeeName
,e1.user_id AS USERID
,e2.name AS ManagerName1
,e2.user_id AS ManagerID1
,e3.name AS ManagerName2
,e3.user_id AS ManagerID2
FROM Employee e1
LEFT JOIN Employee e2
ON e1.managerid = e2.user_id
LEFT JOIN Employee e3
ON e2.managerid = e3.user_id

How to check if there exist only one record for a certain Id

How to check if there exist only one record for a certain Id
I have two tables called Tbl_Company and Tbl_Employee
I am fetching employees as follows-
SELECT DISTINCT emp.employee_id
FROM Tbl_Company comp
, Tbl_Employee emp
WHERE
emp.company_id = comp.company_id
AND emp.company_id = 1234;
This query returns exactly one value.
How can I make sure that above query returns exacly one value for any comany_id I enter.
I tried using solutions given in This post with no success.
Is there any simpler way to do this.
this would return one row per company
SELECT comp.companyid, max(emp.employee_id) lastEmployeeID
FROM Tbl_Company comp
, Tbl_Employee emp
WHERE
emp.company_id = comp.company_id
AND emp.company_id = 1234
GROUP BY comp.companyid
the following query is simple and flexible. it will return a list of all employees which are alone in their companies (returned with full employee information).
you can check if a defined company has one lonely employee by enable condition about company or you can check if employee is a lonely employee by enabling employee condition.
SELECT emp.*
FROM Tbl_Company comp
/*, Tbl_Employee emp*/
WHERE (emp.company_id , 1) in (select t.company_id, count(t.employee_id) from Tbl_Company t )
--AND emp.company_id = 1111 /*filter conditions on company_id*/
--AND emp.employee_id = 1234/*filter conditions on employee_id*/;
I have solved this by using ans by #davegreen100 in comment
SELECT comp.companyid, count(distinct emp.employee_id),
FROM Tbl_Company comp
, Tbl_Employee emp
WHERE
emp.company_id = comp.company_id
AND emp.company_id = 1234
GROUP BY comp.companyid
This will give me the count of employees per company

Count on a database using Count function SQL

I have the database schema like this
Flights(flno,from,to,distance,departs,arrives,price)
Aircraft(aid,aname,cruisingRange)
Certified(employee,aircraft)
Employees(eid,ename,salary)
Where Flno is primary key and Each route corresponds to a "flno".
So I have this question to answer for the Schema
For each pilot, list their employee ID, name, and the number of routes
he can pilot.
I have this SQL, is this correct? ( I can test, as I dont have data for the database).
select eid, ename, count(flno)
from employees, flights
groupby flno
This is a simple questioin, but as everyone is mentioning you don't have any link between employee and flights. The relationships stop at certified.
You obviously have or will create some relationship. I have written a query that will give you the count taking into account that you will have a many to many relationship between employee and flights. Meaning an employee can have many flights and a single flight can be made by many employees.
Flights(flno,from,to,distance,departs,arrives,price)
Aircraft(aid,aname,cruisingRange)
Certified(employee,aircraft)
Employees(eid,ename,salary)
select
e.eid employee_id,
e.ename employee_name,
count(*)
from
employees e
inner join certified c on
c.employee = e.eid
inner join aircraft a on
a.aid = c.aircraft
inner join aircraft_flights af on -- new table that you would need to create
af.aircraft = a.aid and
inner join flights f on
f.flno = af.flno -- not I made up a relationship here which needs to exist in some for or another
group by
e.eid,
e.ename
I hope this at least shows you how to write a count statement correctly, but you should probably brush up on your understanding of joins.
Hope that helps.
EDIT
Without the relationships and working in your comments you could get the count as below.
select
e.eid employee_id,
e.ename employee_name,
count(*)
from
employees e
inner join certified c on
c.employee = e.eid
inner join aircraft a on
a.aid = c.aircraft
inner join flights f on
f.distance <= a.cruisingRange
group by
e.eid,
e.ename

Representing 'not in' subquery as join

I am trying to convert the following query:
select *
from employees
where emp_id not in (select distinct emp_id from managers);
into a form where I represent the subquery as a join. I tried doing:
select *
from employees a, (select distinct emp_id from managers) b
where a.emp_id!=b.emp_id;
I also tried:
select *
from employees a, (select distinct emp_id from managers) b
where a.emp_id not in b.emp_id;
But it does not give the same result. I have tried the 'INNER JOIN' syntax as well, but to no avail. I have become frustrated with this seemingly simple problem. Any help would be appreciated.
Assume employee Data set of
Emp_ID
1
2
3
4
5
6
7
Assume Manger data set of
Emp_ID
1
2
3
4
5
8
9
select *
from employees
where emp_id not in (select distinct emp_id from managers);
The above isn't joining tables so no Cartesian product is generated... you just have 7 records you're looking at...
The above would result in 6 and 7 Why? only 6 and 7 from Employee Data isn't in the managers table. 8,9 in managers is ignored as you're only returning data from employee.
select *
from employees a, (select distinct emp_id from managers) b
where a.emp_id!=b.emp_id;
The above didnt' work because a Cartesian product is generated... All of Employee to all of Manager (assuming 7 records in each table 7*7=49)
so instead of just evaluating the employee data like you were in the first query. Now you also evaluate all managers to all employees
so Select * results in
1,1
1,2
1,3
1,4
1,5
1,8
1,9
2,1
2,2...
Less the where clause matches...
so 7*7-7 or 42. and while this may be the answer to the life universe and everything in it, it's not what you wanted.
I also tried:
select *
from employees a, (select distinct emp_id from managers) b
where a.emp_id not in b.emp_id;
Again a Cartesian... All of Employee to ALL OF Managers
So this is why a left join works
SELECT e.*
FROM employees e
LEFT OUTER JOIN managers m
on e.emp_id = m.emp_id
WHERE m.emp_id is null
This says join on ID first... so don't generate a Cartesian but actually join on a value to limit the results. but since it's a LEFT join return EVERYTHING from the LEFT table (employee) and only those that match from manager.
so in our example would be returned as e.emp_Di = m.Emp_ID
1,1
2,2
3,3
4,4
5,5
6,NULL
7,NULL
now the where clause so
6,Null
7,NULL are retained...
older ansii SQL standards for left joins would have been *= in the where clause...
select *
from employees a, managers b
where a.emp_id *= b.emp_id --I never remember if the * is the LEFT so it may be =*
and b.emp_ID is null;
But I find this notation harder to read as the join can get mixed in with the other limiting criteria...
Try this:
select e.*
from employees e
left join managers m on e.emp_id = m.emp_id
where m.emp_id is null
This will join the two tables. Then we discard all rows where we found a matching manager and are left with employees who aren't managers.
Your best bet would probably be a left join:
select
e.*
from employees e
left join managers m on e.emp_id = m.emp_id
where
m.emp_id is null;
The idea here is you're saying that you want to select everything from employees, including anything that matches in the manager table based on emp_id and then filtering out the rows that actually have something in the manager table.
Use Left Outer Join instead
select e.*
from employees e
left outer join managers m
on e.emp_id = m.emp_id
where m.emp_id is null
left outer join will preserve the rows from m table even if they do not have a match i e table based on the emp_id field. The we filter on where m.emp_id is null - give me all the rows from e where there's no matching record in m table.
A bit more on the subject can be found here:
Visual representation of joins
from employees a, (select distinct emp_id from managers) b implies cross join - all posible combinations between tables (and you needed left outer join instead)
The MINUS keyword should do the trick:
SELECT e.* FROM employees e
MINUS
Select m.* FROM managers m
Hope that helps...
select *
from employees
where Not (emp_id in (select distinct emp_id from managers));

SQL query returning cartesian product

I have some tables:
Employee: id, name, id_suc, id dep, id_sec
Suc : id_suc, name
Dep : id_dep, id_suc, name
Sec : id_sec, id_dep, id_suc, name
Don't blame on me, this is an existing application, I didn't create the Database and can't touch the structure since there is too much data inside and reports depending on it. I'm just trying to modify a report as asked.
I do a query:
SELECT DISTINCT
s.name as sucurs,
d.name as depart,
c.name as section,
e.name AS emp
FROM
employee e
join suc s on (e.id_suc = s.id_suc)
join dep d on (e.id_dep = d.id_dep)
join sec c on (e.id_sec = c.id_sec)
ORDER BY
sucurs, depart, section, emp
and brings me a cartesian product. I want:
sucurs1, depart1, section1, emp1
sucurs1, depart1, section1, emp2
.....
(then on the report I group by suc, then dep, then sec)
instead, I got:
sucurs1, depart1, section1, emp1
sucurs2, depart1, section1, emp1
and so on. It brings ALL sucurs, ALL depart, ALL section and sometimes duplicated emp.
I'm missing something, but don't know what. Any clues?
Well, you're always joining the tables to only employee - it would seem that Dep is also linked to Suc - so you need a second JOIN condition (join not only on id_dep but also on id_suc!). Table Sec even needs three JOIN conditions since it shares three id's with the Employee table.
SELECT DISTINCT
s.name as sucurs,
d.name as depart,
c.name as section,
e.name AS emp
FROM
employee e
INNER JOIN
suc s ON e.id_suc = s.id_suc
INNER JOIN
dep d ON e.id_dep = d.id_dep AND e.id_suc = d.id_suc
INNER JOIN
sec c ON e.id_sec = c.id_sec AND e.id_suc = c.id_suc AND e.id_dep = c.id_dep
ORDER BY
sucurs, depart, section, emp