牛客网sql实战(一)

2019-11-16  本文已影响0人  MisterDo

1.查找最晚入职员工的所有信息
注意:同一天入职的可能有多个人
法一:利用max函数找到最大的hire_date对应的员工信息(最优)

法二:利用order by 和 limit找到最大的一个hire_date对应的员工信息

2.查找入职员工时间排名倒数第三的员工所有信息
注意:同一天入职的可能有多个人
法一:利用order by 和 limit找到倒数第三的hire_date对应的员工信息

法二:同一天入职的如果有多个人,那么倒数第三的员工并不是按照时间日期排的,更严谨的做法,是利用子查询结合distincnt 和order by 和 limit找到入职日期倒数第三的hire_date对应的员工信息

3.查找各个部门当前(to_date='9999-01-01')领导当前薪水详情以及其对应部门编号
以salary为主表,进行内连接查找
4.查找所有已经分配部门的员工的last_name和first_name
以dept_emp为主表,进行内连接查找
5.查找所有员工的last_name和first_name以及对应部门编号dept_no,也包括展示没有分配具体部门的员工
外连接

select e.last_name,e.first_name,d.dept_no
from employees as e left join dept_emp as d 
on e.emp_no=d.emp_no;

6.查找所有员工入职时候的薪水情况,给出emp_no以及salary, 并按照emp_no进行逆序
注意内连接与where并列查询的区别:
内连接是取左右两张表的交集形成一个新表,用FROM并列两张表后仍然还是两张表。如果还要对新表进行操作则要用内连接。从效率上看应该FROM并列查询比较快,因为不用形成新表。本题从效果上看两个方法没区别。

7.查找薪水涨幅超过15次的员工号emp_no以及其对应的涨幅次数t
解决本题的关键在于要记得,sql语句的执行顺序,先group by emp_no,按员工编号进行分组,然后执行select中的count(emp_no) 最后执行having中的过滤条件

一个sql查询语句的主要组成部分为
select --- from --- where --- group by --- having --- order by --- limit --- ;
执行顺序:

  1. from
  2. where
  3. group by
  4. select
  5. having
  6. ordre by
  7. limit
select emp_no,count(emp_no) as t from salaries group by emp_no having t>15;

8.找出所有员工当前(to_date='9999-01-01')具体的薪水salary情况,对于相同的薪水只显示一次,并按照逆序显示

在单表的时候使用distinct,多表的时候使用group by,虽然一般使用group by ,但还是要知道distinct的用法

单表用distinct:

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

多表用group by:

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

9.获取所有部门当前manager的当前薪水情况,给出dept_no, emp_no以及salary,当前表示to_date='9999-01-01'

select d.dept_no,d.emp_no,s.salary from dept_manager as d inner join
salaries as s on d.emp_no=s.emp_no 
and d.to_date='9999-01-01'
and s.to_date='9999-01-01'

10.获取所有非manager的员工emp_no
方法一:

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

方法二:

select emp_no from (select * from employees as e left join dept_manager as d
on e.emp_no=d.emp_no) where dept_no is NUll

11.获取所有员工当前的manager,如果当前的manager是自己的话结果不显示,当前表示to_date='9999-01-01'。
结果第一列给出当前员工的emp_no,第二列给出其manager对应的manager_no。

select e.emp_no,m.emp_no from dept_emp as e 
inner join dept_manager as m 
on e.dept_no=m.dept_no
and e.emp_no<>m.emp_no
and e.to_date='9999-01-01' 
and m.to_date='9999-01-01';

12.获取所有部门中当前员工薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary
1.先内连接两张表
2.按dept_no进行分组
3.找出组内最大薪水的成员

select d.dept_no,d.emp_no,max(s.salary) from dept_emp as d inner join salaries as s 
on d.emp_no=s.emp_no where d.to_date="9999-01-01" and s.to_date="9999-01-01"
group by d.dept_no

13.从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t

select title,count(title) as t from titles group by title having t>=2;

14.从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。
注意对于重复的emp_no进行忽略。

select title ,count(distinct emp_no) as t from titles
group by title having t>=2;

15.查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列

select * from employees where emp_no%2=1 
and  last_name<>"Mary" 
order by hire_date desc;

16.统计出当前各个title类型对应的员工当前(to_date='9999-01-01')薪水对应的平均工资。结果给出title以及平均工资avg

select t.title,avg(s.salary) from titles as t 
inner join salaries as s on t.emp_no=s.emp_no
where t.to_date="9999-01-01" and s.to_date="9999-01-01"
group by t.title;

17.获取当前(to_date='9999-01-01')薪水第二多的员工的emp_no以及其对应的薪水salary

select emp_no,salary from salaries order by salary desc limit 1,1;

改进版:针对于薪水相同的员工,上述做法无法真正得到按薪水排第二的员工信息

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

18.查找当前薪水(to_date='9999-01-01')排名第二多的员工编号emp_no、薪水salary、last_name以及first_name,不准使用order by
从薪水不是第一的里面找最大值

select e.emp_no,max(s.salary),e.last_name,e.first_name
from employees as e inner join salaries as s
on e.emp_no=s.emp_no where s.to_date='9999-01-01' and 
s.salary<>(select max(salary) from salaries where to_date='9999-01-01')

19.查找所有员工的last_name和first_name以及对应的dept_name,也包括暂时没有分配部门的员工

select e.last_name,e.first_name,d.dept_name
from employees as e left join 
(select * from dept_emp inner join departments on dept_emp.dept_no=departments.dept_no) as d
on e.emp_no=d.emp_no

20.查找员工编号emp_no为10001其自入职以来的薪水salary涨幅值growth

select (max(salary)-min(salary)) as growth from salaries where emp_no='10001'

更严谨的做法:

SELECT ( 
(SELECT salary FROM salaries WHERE emp_no =`10001` ORDER BY to_date DESC LIMIT 1) -
(SELECT salary FROM salaries WHERE emp_no =`10001` ORDER BY to_date ASC LIMIT 1)
) AS growth

21.查找所有员工自入职以来的薪水涨幅情况,给出员工编号emp_no以及其对应的薪水涨幅growth,并按照growth进行升序

select a.emp_no,(b.salary-c.salary) as growth
from employees as a 
inner join salaries as b on a.emp_no=b.emp_no and b.to_date='9999-01-01'
inner join salaries as c on a.emp_no=c.emp_no and c.from_date=a.hire_date
order by growth

22.统计各个部门对应员工涨幅的次数总和,给出部门编码dept_no、部门名称dept_name以及次数sum

select d.dept_no,d.dept_name,count(d.dept_no) as sum from departments as d inner join 
(select * from dept_emp as a inner join salaries as b 
on a.emp_no=b.emp_no) as c on d.dept_no=c.dept_no
group by d.dept_no
上一篇 下一篇

猜你喜欢

热点阅读