SQL刷题从0到100,位运算竟然在SQL里也有这么大作用!(15 16 17)

233 阅读3分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

大家好,我是老表,sql刷题继续更新啦,后面每次遇到困难题后就更新,但是这次困难题在21,隔的蛮远的,所以先分享接下来三题,明天更新后面三题。

今天更新3道题,2(简单)+1(中等)。

  • SQL15 查找employees表emp_no与last_name的员工信息(简单)
  • SQL16 统计出当前各个title类型对应的员工当前薪水对应的平均工资(中等)
  • SQL17 获取当前薪水第二多的员工的emp_no以及其对应的薪水salary(简单)

SQL15 查找employees表emp_no与last_name的员工信息

我的思路: 这个从题目标题无法看出需求,需要具体看描述:查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列。直接按照需求写sql即可,这里判断员工编号是否为奇数,可以使用%对2取余数进行判断,余数为1即为奇数。

我的题解:

select *
from employees
where emp_no % 2 = 1
and last_name != 'Mary'
order by hire_date desc 
;

涉及知识点:

  • 完整sql执行顺序(每天看一遍,不信记不住):
from -> where -> group by -> having -> select -> order by -> limit
  • sql 取余数可以直接使用 %
  • order by hire_date desc 按hire_date列降序排序

提交结果:
其他题解:

select *
from employees
where emp_no&1 = 1
and last_name != 'Mary'
order by hire_date desc 
;

这里判断是否为奇数,也可以使用位运算进行判断,任何数和1的位运算结果如果是1,则是奇数,否则运算结果为0,则为偶数。

这个是真的涨见识了,位运算很好的应用实践。

SQL16 统计出当前各个title类型对应的员工当前薪水对应的平均工资

我的思路: 比较常规,首先明确需求:结果给出title以及平均工资avg,并且以avg升序排序,所以先将titles和salaries进行join连接,然后根据title进行分组求salary的平均值即可,最后按照平均值进行升序排序。

我的题解:

select title, avg(salary) as avg_s
from (
select a.emp_no, a.title, b.salary
from titles as a
join salaries as b
on a.emp_no = b.emp_no
and a.to_date = b.to_date
and a.to_date = '9999-01-01') as c 
group by title
order by avg_s
;

涉及知识点:

  • 完整sql执行顺序(每天看一遍,不信记不住):
from -> where -> group by -> having -> select -> order by -> limit
  • 窗口函数:avg使用
  • group by 分组
  • order by 排序,默认是升序

提交结果:

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

我的思路: 这个只有一个表,蛮简单的,直接按照salary降序排序,取出第二列数据即可。

我的题解:

select emp_no, salary
from salaries
where to_date = '9999-01-01'
order by salary desc
limit 1,1
;

涉及知识点:

  • 完整sql执行顺序(每天看一遍,不信记不住):
from -> where -> group by -> having -> select -> order by -> limit
  • order by salary desc 降序排序
  • 从指定位置开始取出指定行:limit m,n 从m+1行开始,取出n行数据

提交结果:

其他题解: 上面解法有局限性,如果排名第一的有很多个,那么取出来的还是薪水最高的,所以好的方法应该是直接按第二的薪水进行筛选。

所以我们先找出第二薪水是多少,然后筛选出薪水等于第二薪水的行即可。

select emp_no, salary
from salaries
where to_date = '9999-01-01'
and salary = (
    select salary
    from salaries
    group by salary
    order by salary desc 
    limit 1,1
)
order by salary desc
;