I have a table; containing 2 fields, name and salary. I used below script to find the 3rd maximum salary.
SELECT DISTINCT sal
FROM downtodate1.emp e1
WHERE 3 = (SELECT COUNT(DISTINCT sal) FROM downtodate1.emp e2 WHERE e1.sal<= e2.sal);
I want to know how it works and why 3 is used here?
select distinct sal
from downtodate1.emp AS e1
where 3 = (
select count(distinct sal)
from downtodate1.emp e2
where e1.sal <= e2.sal
);
Consider you have a table like this:
sal
---
3
3
2
1
1
0
With this part
select distinct sal
from downtodate1.emp AS e1
you'll get the result
sal
---
3
2
1
0
That makes 4 distinct salaries.
Now the subquery
select count(distinct sal)
from downtodate1.emp e2
where e1.sal <= e2.sal
is executed for every row in your main query. It calculates the number of distinct values which are lower or equal the row in your main query. So the result of this is actually (but not displayed):
sal | count(distinct sal) where e1.sal <= e2.sal
------------------------------------------------
3 1
3 1
2 2
1 3
1 3
0 4
With the distinct from the main query you'll get this result:
sal | count(distinct sal) where e1.sal <= e2.sal
------------------------------------------------
3 1
2 2
1 3
0 4
and with the WHERE
clause 3 = (/*subquery*/)
you'll get only
sal | count(distinct sal) where e1.sal <= e2.sal
------------------------------------------------
1 3
this row. So the result is 1
.
Hope it's clear now.
Here's a faster method...
SELECT salary
FROM
(
SELECT salary
, @prev := @curr
, @curr := salary
, @rank := IF(@prev = @curr, @rank, @rank+1) rank
FROM employee
CROSS
JOIN
( SELECT @curr := null, @prev := null, @rank := 0) sel1
ORDER
BY salary DESC
) x
WHERE rank = 3;
Use This....
SELECT DISTINCT sal FROM downtodate1.emp e1
WHERE 2 = (SELECT COUNT(DISTINCT sal) FROM downtodate1.emp e2 WHERE e1.sal> e2.sal);
WHERE 0 =1st Highest Sal
WHERE 1 =2nd Highest Sal
WHERE 2 =3rd Highest Sal
WHERE 3 =4th Highest Sal
Index start from zero(0)
Instead of this...
SELECT DISTINCT sal FROM downtodate1.emp e1
WHERE 3 = (SELECT COUNT(DISTINCT sal) FROM downtodate1.emp e2 WHERE e1.sal<= e2.sal);
Instead you can use this to find the Nth max salary
SELECT sal FROM emp
ORDER BY sal DESC
LIMIT N,1
N be the Nth number.
Perhaps reformatting the query will clarify:
select distinct sal
from downtodate1.emp AS e1
where 3 = (
select count(distinct sal)
from downtodate1.emp e2
where e1.sal <= e2.sal
);
The result of the subquery is being compared to 3, as the number of preceding rows for the requried row. This is (potentially) a O(N^2) calculation, but that may be sufficient in this case.
this 3 is the same as you writed
where
(select count(distinct sal) from downtodate1.emp e2 where e1.sal <= e2.sal) = 3 ;
where a = 3
or where 3 = the count of distinct sal
使用子查询检索员工最高工资记录的简单方法
select * from Employee where salary in (select max(salary) from Employee)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.