牛客网sql练习题解 (1-11)

文章目录

    • 简介
    • 题解
      • 1
      • 2
      • 3
      • 4 + 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

简介

我将分批总结牛客网sql题解,当然leecode也是我比较推荐的sql在线OJ,至于为什么我不写leecode,是因为我不是会员,hahah~

往期文章:
牛客网sql练习题解 (1-11)
牛客网sql练习题解(12-21)
牛客网sql练习题解(22-32)
牛客网sql练习题解(34-42)

题解

1

牛客网sql练习题解 (1-11)_第1张图片
其实是一个topN问题

select * 
from employees
order by hire_date desc 
limit 1;
或者是:

select * 
from employees
order by hire_date desc
limit 1 offset 0;

或者是:

select *
from employees
order by hire_date desc
limit 0,1;
从第0条记录向后读取一个,也就是第

牛客网sql练习题解 (1-11)_第2张图片

或者使用子查询

select *
from employees
where hire_date  = (
    select max(e.hire_date) 
    from employees e
);

牛客网sql练习题解 (1-11)_第3张图片

2

牛客网sql练习题解 (1-11)_第4张图片
同样topN问题的思路解决:

select * 
from employees
order by hire_date desc
limit 1 offset 2;

牛客网sql练习题解 (1-11)_第5张图片

注:
以下的两种方式均表示取2,3,4三条条数据。 1.select* from test LIMIT 1,3; 当limit后面跟两个参数的时候,第一个数表示要跳过的数量,后一位表示要取的数量。 2.select * from test LIMIT 3 OFFSET 1;(在mysql 5以后支持这种写法) 当 limit和offset组合使用的时候,limit后面只能有一个参数,表示要取的的数量,offset表示要跳过的数量 。

当存在重复数据的时候:

select *
from employees
where hire_date = (
    select distinct e.hire_date
    from employees e
    order by e.hire_date desc
    limit 1 offset 2
);

牛客网sql练习题解 (1-11)_第6张图片

3

牛客网sql练习题解 (1-11)_第7张图片

SELECT s.*, d.dept_no
FROM salaries AS s , dept_manager AS d 
WHERE d.to_date='9999-01-01'
AND s.to_date='9999-01-01'
AND s.emp_no = d.emp_no;

牛客网sql练习题解 (1-11)_第8张图片

SELECT s.*, d.dept_no
FROM salaries s inner join dept_manager d
on d.emp_no = s.emp_no
WHERE d.to_date='9999-01-01'
AND s.to_date='9999-01-01';

牛客网sql练习题解 (1-11)_第9张图片

注:
from两个表的顺序如果颠倒就会报错。
我觉得和SQL的执行顺序有关。

4 + 5

具体的题目大致相同,注意join, inner join ,outer join, left join , right join就好
牛客网sql练习题解 (1-11)_第10张图片

6

牛客网sql练习题解 (1-11)_第11张图片
首先来看我的解法:

select t1.emp_no, s.salary
from (
    select *
    from employees e1
    group by e1.emp_no
    having min(e1.hire_date)
    order by e1.emp_no desc
) t1 left join salaries s
on t1.emp_no = s.emp_no and t1.hire_date = s.from_date;

首先我们利用emp_no和最小的hire_date来经employee进行过滤,然后join一下。

牛客网sql练习题解 (1-11)_第12张图片

但是还有更简单的写法

select e.emp_no, s.salary
from employees e, salaries s
where e.emp_no = s.emp_no and e.hire_date = s.from_date
order by e.emp_no desc;

牛客网sql练习题解 (1-11)_第13张图片

7

牛客网sql练习题解 (1-11)_第14张图片
考察group by 和having的使用
分组聚合函数的考察

select emp_no, count(*) as t
from salaries
group by emp_no
having count(*) > 15;

牛客网sql练习题解 (1-11)_第15张图片
思考:
这道题问的是涨幅,所以如果考虑严格意义上的涨幅:

select s1.emp_no, count(*) as t
from salaries s1 inner join salaries s2
on s1.emp_no = s2.emp_no and s1.to_date = s2.from_date
where s1.salary < s2.salary
group by s1.emp_no
having count(*) > 15;

注:inner Join 和left join的区别
left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录
  right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录
  inner join(等值连接) 只返回两个表中联结字段相等的行

8

牛客网sql练习题解 (1-11)_第16张图片

没什么难度,考察的基本distinct 和 order by 用法

select distinct salary 
from salaries
where to_date = '9999-01-01'
order by salary desc;

牛客网sql练习题解 (1-11)_第17张图片

9

牛客网sql练习题解 (1-11)_第18张图片
这道题不难,同时写法挺多的。

select dm.dept_no, dm.emp_no, s1.salary
from dept_manager dm, (
    select * 
    from salaries a
    where a.to_date = '9999-01-01'
) s1
where dm.emp_no = s1.emp_no and dm.to_date = '9999-01-01';

牛客网sql练习题解 (1-11)_第19张图片

10

牛客网sql练习题解 (1-11)_第20张图片

select distinct emp_no
from employees
where emp_no not in (
    select distinct emp_no
    from dept_manager
);

牛客网sql练习题解 (1-11)_第21张图片

11

牛客网sql练习题解 (1-11)_第22张图片

这题我觉得注意一下不等于的表示吧

select d.emp_no, dm.emp_no as manager_no
from dept_emp d, dept_manager dm
where d.dept_no = dm.dept_no and dm.to_date = '9999-01-01'
and d.emp_no <> dm.emp_no;

牛客网sql练习题解 (1-11)_第23张图片

大家共勉~~

你可能感兴趣的:(数据挖掘,大数据)