SQL练习:这个sql写的妙啊!1(较难)+1(中等)+1(困难)

简介: SQL练习:这个sql写的妙啊!1(较难)+1(中等)+1(困难)

简说Python,号主老表,Python终身学习者,数据分析爱好者,从18年开始分享Python知识,原创文章227篇,写过Python、SQL、Excel入门文章,也写过Web开发、数据分析文章,老表还总结整理了一份2022Python学习资料和电子书资源,关注后私信回复:2022 即可领取。

SQL18 获取当前薪水第二多的员工的emp_no以及其对应的薪水salary

image.pngimage.png

我的思路: 紧接上一题,和sql17的区别就是 将员工薪水另外存了一张表,另外要求不能使用order by 排序。我们可以先找出薪水表中第二高的薪水,然后从employees、salaries两表中筛选出薪水第二高的员工信息。

取第二高的薪水,这里采用的是去除当前最高薪水后,再查找剩余薪水中的最高薪水。

我的题解:

select a.emp_no, b.salary, a.last_name, a.first_name
from employees as a
join salaries as b
on a.emp_no = b.emp_no
and b.salary = (
    select max(salary)
    from salaries
    where to_date = '9999-01-01'
    and salary < (
        select max(salary)
        from salaries
        where to_date = '9999-01-01'
    )
)
;

涉及知识点:

  • 完整sql执行顺序(每天看一遍,不信记不住):
from -> where -> group by -> having -> select -> order by -> limit
  • 窗口函数max取最大值

提交结果:

image.png

其他题解:

image.png这里有个大神三玫提供了另外一种找第二高薪水的方法,通过salaries自连接,连接条件是s1.salary <= s2.salary,这样后,再根据s1.salary分组,然后count(distinct s2.salary) = 2就是第二高薪水。

select a.emp_no, b.salary, a.last_name, a.first_name
from employees as a
join salaries as b
on a.emp_no = b.emp_no
and b.salary = (
    select s1.salary
    from salaries as s1
    join salaries as s2
    on s1.salary <= s2.salary
    and s1.to_date = s2.to_date
    and s1.to_date = '9999-01-01'
    group by s1.salary
    having count(distinct s2.salary) = 2
    )
;

这个思路真的特别巧妙,刚开始你可能会比较懵,不知道为什么这样就可以筛选出第二高薪水了,但是你一画图,举例子操作下,瞬间就能明白。

这里的原理可以归纳为:大于等于自己的数值的个数一定等于自己的降序排序的位数。

例如:在集合{100,98,97,89}中,大于等于98的只有100,98,所以98在这个集合中必然是第二大的数。

image.png评论区也有人做了效率对比,当数据量上升时,该方法效率会大大降低,其实原因也很简单,salaries变大,自连接自然会消耗大量时间。

image.png

SQL19 查找所有员工的last_name和first_name以及对应的dept_name

image.pngimage.png

我的思路: 这个题目和sql5是类似的,现在多了一个departments表,输出里把dept_no改成了dept_name,所以在原来的解法中,dept_emp表先与departmentsjoin,然后再和employees连接即可。

image.png

我的题解:

select a.last_name, a.first_name, b.dept_name
from (
    select emp_no, last_name, first_name
    from employees) as a
left join (
    select d1.emp_no, d2.dept_name
    from dept_emp as d1
    join departments as d2
    on d1.dept_no = d2.dept_no
) as b
on b.emp_no = a.emp_no
;

涉及知识点:

  • 完整sql执行顺序(每天看一遍,不信记不住):
from -> where -> group by -> having -> select -> order by -> limit
  • left join

提交结果:

image.png

SQL21 查找在职员工自入职以来的薪水涨幅情况

image.pngimage.png

我的思路: 这里需要求每个在职员工从入职开始到现在的薪水涨幅情况,这里直接找出每个在职员工入职时薪水,和当前薪水,然后求差即可。

这题比较有意思的是需要理解清楚以下几个日期字段含义:

  • employees.hire_date:表示雇佣日期,可以理解为入职日期;
  • salaries.from_date:表示薪水开始时间;
  • salaries.to_date:表示薪水结束时间,如果为9999-01-01,则表示为当前在职员工。

我的题解:

select s1.emp_no, (s2.salary-s1.salary) as growth
from (
    -- 入职薪水
    select a1.emp_no, a2.salary
    from employees as a1
    join salaries as a2
    on a1.emp_no = a2.emp_no
    and a1.hire_date = a2.from_date
) as s1 
join 
(
    -- 当前薪水
    select emp_no, salary
    from salaries
    where to_date = '9999-01-01'
) as s2
on s1.emp_no = s2.emp_no
order by growth
;

涉及知识点:

  • 完整sql执行顺序(每天看一遍,不信记不住):
from -> where -> group by -> having -> select -> order by -> limit
  • join 连接
  • order by 分组

提交结果:

image.png

题目地址:https://www.nowcoder.com/ta/sql

相关文章
|
3月前
|
SQL Perl
PL/SQL经典练习
PL/SQL经典练习
|
3月前
|
SQL 分布式计算 数据挖掘
Hive SQL初级练习(30题)
Hive SQL初级练习(30题)
|
10月前
|
SQL 存储 Java
Mybatis实战练习四【单个条件(动态SQL)&添加数据】(下)
Mybatis实战练习四【单个条件(动态SQL)&添加数据】
|
10月前
|
SQL 存储 关系型数据库
【MYSQL高级】Mysql 表的七种连接方式【附带练习sql】
【MYSQL高级】Mysql 表的七种连接方式【附带练习sql】
125 0
|
2月前
|
SQL 存储 数据库
技术好文:SQL查询语句基本练习
技术好文:SQL查询语句基本练习
|
10月前
|
SQL Java 数据库连接
Mybatis实战练习四【单个条件(动态SQL)&添加数据】(上)
Mybatis实战练习四【单个条件(动态SQL)&添加数据】
|
3月前
|
SQL
SQL语句多表查询练习
SQL语句多表查询练习
21 0
|
3月前
|
SQL 关系型数据库 MySQL
mysql查询语句练习总结(涵盖所有sql语法)
mysql查询语句练习总结(涵盖所有sql语法)
|
9月前
|
SQL 算法 JavaScript
在线就能用的 SQL 练习平台(附SQL学习文档)
在线就能用的 SQL 练习平台(附SQL学习文档)
362 0
|
SQL 数据挖掘 数据库
牛客网之SQL刷题练习——一个实用的网站
牛客网之SQL刷题练习——一个实用的网站
328 0