数据库实战每日6题(1 ~ 6)

数据库实战每日6题(1 ~ 6)

  • 查找最晚入职员工的所有信息
  • 查找入职员工时间排名倒数第三的员工所有信息
  • 查找当前薪水详情以及部门编号dept_no
  • 查找所有已经分配部门的员工的last_name和first_name
  • 查找所有员工的last_name和first_name以及对应部门编号dept_no
  • 查找所有员工入职时候的薪水情况

查找最晚入职员工的所有信息

题目链接

题目

在这里插入图片描述

解析

  • 思路一: 使用嵌套查询(子查询),内层查询先查询出来表中的最大的hire_date,外层再查一次;
  • 思路二: 按照hire_date降序排列,然后使用limit关键字取出第一项即可;
select * from employees where hire_date = (select max(hire_date) from employees);

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

select * from employees order by hire_date desc limit 1;

注意limit关键字的使用:

  • LIMIT m,n : 表示从第m+1条开始,取n条数据;
  • LIMIT n : 表示从第0条开始,取n条数据,是limit(0,n)的缩写。

查找入职员工时间排名倒数第三的员工所有信息

题目链接

题目

在这里插入图片描述

解析

  • 思路一: 直接使用desc hire_date 降序排列,然后使用limit来选出倒数第三个;
  • 思路二: 上面的思路如果hire_date 有重复的话,就不能选到真正的名词,所以可以使用distinct关键字选出不重复的hire_date,然后排序,这个查询嵌套在内查询中;
-- 简单的想法
select * from employees order by hire_date desc limit 2,1;


-- 严密的思路
select * from employees
where hire_date = 
    -- 先筛选出不重复的 hrie_date 然后再排序,然后再选择倒数第三的 
    (select distinct hire_date from employees order by hire_date desc limit 2,1);
    

查找当前薪水详情以及部门编号dept_no

题目链接

题目

在这里插入图片描述

解析

  • 思路一: 使用多表查询,其中使用where 条件来连接两个表;
  • 思路二: 使用inner join来连接查询,on 后面带上条件;

注意这里使用部门表作为主表不能通过,可能因为两个表的逻辑关系,题目要求是薪水情况以及部门编号;
以下三种方式都可以:


-- 不使用join
select tb_s.*,tb_d.dept_no
from salaries as tb_s,dept_manager as tb_d
where tb_s.emp_no = tb_d.emp_no
and tb_s.to_date = '9999-01-01'
and tb_d.to_date = '9999-01-01';

-- 使用join
select tb_s.*,tb_d.dept_no
from salaries as tb_s inner join dept_manager as tb_d 
on tb_s.emp_no = tb_d.emp_no
and tb_s.to_date = '9999-01-01'
and tb_d.to_date = '9999-01-01';

select tb_s.*,tb_d.dept_no
from salaries as tb_s inner join dept_manager as tb_d 
on tb_s.emp_no = tb_d.emp_no
where tb_s.to_date = '9999-01-01' and tb_d.to_date = '9999-01-01';

查找所有已经分配部门的员工的last_name和first_name

题目链接

题目

在这里插入图片描述

解析

  • 思路一: 使用等值连接,可以使用where 连接,也可以使用join;
  • 思路二: 直接使用自然连接 natural join;

注意几种连接的区别:

在这里插入图片描述
在这里插入图片描述

-- 等值连接 where
select tb_e.last_name,tb_e.first_name,tb_d.dept_no
from employees as tb_e,dept_emp as tb_d
where tb_e.emp_no = tb_d.emp_no;

-- 等值连接 join 连接查询
select tb_e.last_name,tb_e.first_name,tb_d.dept_no
from employees as tb_e inner join dept_emp as tb_d
on tb_e.emp_no = tb_d.emp_no;

-- 使用自然连接 (两个表的同一列属性的值相同)
select tb_e.last_name,tb_e.first_name,tb_d.dept_no
from employees tb_e natural join dept_emp tb_d;

查找所有员工的last_name和first_name以及对应部门编号dept_no

题目连接

题目

在这里插入图片描述

解析

  • 这里使用左连接查询,左边的全,右边的为null的就显示null;

注意JOIN的区别:

  • INNER JOIN 两边表同时有对应的数据,即任何一边缺失数据就不显示;
  • LEFT JOIN 会读取左边数据表的全部数据,即便右边表无对应数据;
  • RIGHT JOIN 会读取右边数据表的全部数据,即便左边表无对应数据;

注意on与where区别,两个表连接时用on,在使用LEFT JOIN时,on和where条件的区别如下:

  • on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。
  • where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有LEFT JOIN的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。

更多关于ON 和 WHERE的知识看这篇博客

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

查找所有员工入职时候的薪水情况

题目链接

题目

在这里插入图片描述

解析

  • 测试数据中,salaries.emp_no不唯一(因为号码为emp_no的员工会有多次涨薪的可能,所以在salaries中对应的记录不止一条),employees.emp_no唯一,即salaries的数据会多于employees,因此需先找到tb_e.emp_no在tb_s表中对应的记录salaries.emp_no,则有限制条件tb_e.emp_no = tb_s.emp_no;
  • 根据题意注意到salaries.from_date 和employees.hire_date的值应该要相等,因此有限制条件 tb_e.hire_date = tb_s.from_date;
select tb_e.emp_no,tb_s.salary 
from employees as tb_e inner join salaries as tb_s
on tb_e.emp_no = tb_s.emp_no
and tb_e.hire_date = tb_s.from_date -- 注意这个员工入职时候的薪水
order by tb_e.emp_no desc;

猜你喜欢

转载自blog.csdn.net/zxzxzx0119/article/details/82872824
6