SQL练习:第二高的薪水——Distinct 和 Limit 的执行顺序

题目:第二高的薪水——LeetCode
答案:官方答案解析
题目:
编写一个 SQL 查询,获取 Employee 表中第二高的薪水(Salary) 。

Id Salary
1 100
2 200
3 300

例如上述 Employee 表,SQL查询应该返回 200 作为第二高的薪水。如果不存在第二高的薪水,那么查询应返回 null。

SecondHighestSalary
200

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/second-highest-salary
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解析
Sql Server:(方法一)
思路: 先取得列表中Salary的最大值,然后在列表小于最大值的部分里取最大值,即得到第二高薪酬。

/* Write your T-SQL query statement below */
select max(Salary)  as "SecondHighestSalary"
from Employee
where Salary < (select max(Salary) from Employee)

方法优点:属于标准SQL语言,各数据库服务器通用
方法缺点:运行速度很慢,跟limit和offset连用比起来,相差一个数量级。

MySQL:(方法二)
思路: 先对列表进行降序,然后使用LIMIT 1, 1,直接取得列表中的第二位。同时,由于题目要求“如果不存在第二高的薪水,那么查询应返回 null”,因此在最后结果上套用IFNULL函数。

SELECT
    IFNULL(
      (SELECT DISTINCT Salary
       FROM Employee
       ORDER BY Salary DESC
        LIMIT 1, 1),
    NULL) AS SecondHighestSalary

Distinct 和 Limit 的执行顺序

在使用MySQL解答题目的时候发现,代码中不加入DISTINCT(位于方法二的第三行),则提示解答错误;加入DISTINCT,则提交通过。刚开始一直无法理解差别在哪儿,后来发现与LIMIT 的使用方法,以及Distinct 和 Limit 的执行顺序有关。

LIMIT语句 (LIMIT i, n): 查询n条数据,索引从i 到 i+n-1,第 i+1条记录到第 i+n条记录。i:为查询结果的索引值(默认从0开始),当i=0时可省略 i。因此 LIMIT 1, 1的意思是,从第二行开始取数据,一共取一条数据。

Distinct 和 Limit 的执行顺序:Distinct 和 Order BY语句先执行, Limit最后执行。

当仅有一个ID拥有第一高薪水时,加Distinct 与不加,返回的结果是相同的。当有两个及以上ID拥有第一高薪水时,两者存在区别。
此时,不使用Distinct意味着不去重直接排序,数据的前两条均为第一高薪水,LIMIT1, 1 从第二行开始取,由于第二条依旧是最高的薪水,那么取到的记录仍未第一高薪水,而不是第二高薪水。使用Distinct,即去重并排序后,数据中第一高薪水仅占一条,第二条即为第二高薪水,则取出的为第二高薪水数据。


版权声明:本文为woooooood原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END
< <上一篇
下一篇>>