Need help on a query - sql

I have a table employees that looks like this:
Id Name Manager_Id
1 ABC 4
2 DEF 20
3 GHI 30
4 JKL 40
The below query does not return any results. I was expecting that it would return "JKL". What am I missing here?
select e1.Name from Employees e1 where e1.id =
(select e2.manager_id from employees e2 where e2.id = e1.id);

If you break this query down from the outside in, you're expecting to find a record where e1.id = e2.manager_id but also where e2.id = e1.id. In other words, you're querying for a record where id = manager.id, which simply does not exist.
What I assume you're trying to do is select all the records where the id exists as a manager_id in the table.
This can be done much more simply with an in operator:
SELECT name
FROM employees
WHERE id IN (SELECT manager_id FROM employees)

use in, not = :
select e1.Name from Employees e1 where e1.id IN
(select e2.manager_id from employees e2 where e2.id = e1.id);
The = operator is for testing if scalars are the same. IN tests set membership.

Related

How to find levels of managers in self-referenced key

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)

EXISTS command vs IN command

For reference, I am trying to answer a SQL question at: https://www.w3resource.com/sql-exercises/sql-subqueries-exercise-21.php
And the answer is:
SELECT first_name, last_name, department_id
FROM employees
WHERE EXISTS (SELECT *
FROM employees
WHERE salary > 3700);
But can someone please explain why the above does not return the same result as:
SELECT e1.first_name, e1.last_name, e1.department_id
FROM employees AS e1
WHERE e1.employee_id IN (SELECT e2.employee_id
FROM employees AS e2
WHERE e2.salary > 3700);
The EXISTS clause gives a value of TRUE or FALSE. The statement that you've written will give a value of TRUE if there is any row at all in employees with a salary of more than 3700. You did not include any condition that requires that row to match the id of the employee you're checking.
If you want to add such a condition, you'd write (assuming a unique employee id exists and is called employee_id):
SELECT first_name, last_name, department_id
FROM employees E1
WHERE EXISTS
(SELECT *
FROM employees
WHERE salary > 3700 AND employee_id = E1.employee_id )
The first has no correlation clause. Hence, it either returns all rows in employees (if any row matching the condition exists). Or it returns no rows in employees (if no such rows exist).
The second is comparing the rows in the subquery to the id in the outer query. The equivalent query using exists would be:
SELECT e1.first_name, e1.last_name, e1.department_id
FROM employees AS e1
WHERE EXISTS (SELECT e2.employee_id
FROM employees AS e2
WHERE e2.employee_id = e1.employee_id AND
e2.salary > 3700
);
Of course, one would expect the employee_id to be the primary key for a table called employees. So this would do the same thing:
SELECT e1.first_name, e1.last_name, e1.department_id
FROM employees AS e1
WHERE e1.salary > 3700

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

Self Join with Correlated Subquery

I need to find an employee with a salary greater than their Manager. For this, I used to following query and it works;
SELECT
e1.EmpID
,e1.EmpName
,e1.EmpSalary
,e1.ManagerID
FROM empsalary e
INNER JOIN empsalary e1 ON e.EmpID = e1.ManagerID
WHERE e1.EmpSalary > e.EmpSalary
But following one is not working. I want to know why it is not? Why it's result is null? What should be correct format?
SELECT *
FROM empsalary as e
WHERE e.empsalary=(
SELECT e1.empsalary
FROM empsalary as e1
WHERE e.EmpID = e1.ManagerID
AND e1.EmpSalary > e.EmpSalary)
Sample data and code here;
EmpID EmpName EmpSalary ManagerID
----------- ---------- -------------------- -----------
1 Neevan 100000 6
2 Mukesh 30000 6
3 Disha 50000 6
4 Martin 90000 6
5 Roy 170000 6
6 Anvesh 168000 NULL
CREATE TABLE empsalary
(
EmpID INT
,EmpName VARCHAR(10)
,EmpSalary BIGINT
,ManagerID INT
)
INSERT INTO empsalary
VALUES
(1,'Neevan',100000,6)
,(2,'Mukesh',30000,6)
,(3,'Disha',50000,6)
,(4,'Martin',90000,6)
,(5,'Roy',170000,6)
,(6,'Anvesh',168000,NULL)
Your correlations are all backwards. The right way is:
SELECT e.*
FROM empsalary e
WHERE e.empsalary > (SELECT m.empsalary
FROM empsalary m
WHERE m.EmpID = e.ManagerID
);
Notice that I have used the m table alias for the manager record. This helps to follow the logic.
There's no need for me to re-write how to do it, as Gordon has done a good enough job already, but I can explain why yours returned null...
For me to answer this, I needed to re-write yours slightly to help me to read it. It is essentially the same as yours. Also, similarly to how Gordon has done, I've substituted e for m and e1 for e. I've also called your tables tblSalaries, so that the table names aren't the same as the column name:
SELECT *
FROM tblSalaries as m
WHERE m.empsalary=(
SELECT e.empsalary
FROM tblSalaries as e
WHERE e.ManagerID = m.EmpID
AND e.EmpSalary > m e.EmpSalary)
If we work backwards and interpret the last part firstly:
...
(
SELECT e.empsalary
FROM tblSalaries as e
WHERE e.ManagerID = m.EmpID
AND e.EmpSalary > m.EmpSalary)
Firstly, WHERE m.ManagerID = e.EmpID is saying 'Find all employees in e who's manager ID is the same as the employee ID in m'. Considering there is only one managerID (6), then records 1-5 from e will all match the manager record, on m (6) on this.
Your next clause AND e.EmpSalary > m.EmpSalary is finding those who's salary is greater than the managers'. Therefore, you are left with record 5 (Roy) as you intended.
Now to return to your main query:
SELECT *
FROM tblSalaries as m
WHERE m.empsalary= (...tblSalaries as e...)
We have established that table e in the brackets has returned Roy, but we have also established that it only matches records in table m, where m is a manager. Ultimately, you are asking then to find where the manager's salary = Roy's salary; the answer, null.

Can't insert date from table to other with 2 condition

i want insert date from table to other
with 2 condition from same row
(view picture in yellow part)
thanks
The problem is that the IN in the where clause can only have one colymn, not two. You could re-write it as:
from emp e
inner join emp2 e2 on e.Id = e2.Id and e.storeId = e2.storeId
I think that this would get you the effect.
You can declare only one field in "not in subselect" approach.
You should give this workaround a try:
select .... from emp e
where not exists (
select 1 from emp2 e2 where e.id = e2.id and e.storeid = e2.storeid
)
I guess it provides exactly the same result as you need