Reputation: 85
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)
Upvotes: 1
Views: 3230
Reputation: 626
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.EmpI
D 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
.
Upvotes: 0
Reputation: 1271161
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.
Upvotes: 2