MySQL 实例练习---day01

One that would the fruit must climb the tree.
要吃果子就得上树。 ——Thomas Fuller

SQL1

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

方法一:使用子查询语句
1、先查询到 hire_date 字段中的最大值,即最晚入职日期
2、将上面的查询结果作为 employees 表的 where 子句条件

SELECT * FROM employees 
    WHERE hire_date=(
    SELECT MAX(hire_date) 
        FROM employees
    );

方法二:使用 order by 降序排序,limit 分页查询
1、使用 order by 子句对 hire_date 字段进行排序。默认是生序排序(ASC),在这里采用降序排序(DESC),将日期按从大到小排序
2、再结合使用 limit 子句取出想要的查询结果集,limit m, n(m 代表从 m+1 行开始取,n 代表取出多少行)

SELECT * FROM employees 
    ORDER BY hire_date DESC 
    LIMIT 1;

对比:当同一天有多个员工同时入职时,方法一可以查询到日期最大的所有记录,但方法二只能查询到 limit 指定显示的数量

SQL2

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

SELECT * FROM employees
    ORDER BY hire_date DESC
    LIMIT 2, 1;

运行时间52ms 占用内存7480KB

#如果同一天有多个员工同时入职时,应该使用 
#distinct 关键字对相同日期进行去重
SELECT * FROM employees
    WHERE hire_date=(
        SELECT DISTINCT hire_date
        FROM employees
        ORDER BY hire_date DESC
        LIMIT 2, 1);

运行时间54ms 占用内存7476KB

SQL3

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

问题:查找各个部门当前领导的薪水详情以及其对应部门编号dept_no,输出结果以salaries.emp_no升序排序,并且请注意输出结果里面dept_no列是最后一列

SELECT salaries.*, dept_manager.dept_no 
    FROM salaries, dept_manager
    WHERE salaries.emp_no = dept_manager.emp_no
    ORDER BY salaries.emp_no ASC;

SQL4

查找所有已经分配部门的员工的last_name和first_name以及dept_no,未分配的部门的员工不显示

/*使用 where 子句进行过滤查询,找到两张表关联的字段
employees.emp_no = dept_emp.emp_no*/
SELECT employees.last_name, employees.first_name, dept_emp.dept_no
    FROM employees, dept_emp
    WHERE employees.emp_no = dept_emp.emp_no;

SQL5

查找所有已经分配部门的员工的last_name和first_name以及dept_no,也包括暂时没有分配具体部门的员工

根据题目要求,可以使用多表查询中外连接的左外连接(左侧表查询出的字段全部显示),已分配部门的员工显示对应的部门号,未分配部门的员工部门号则为空

SELECT employees.last_name, employees.first_name, dept_no
    FROM employees
    LEFT JOIN dept_emp
    ON employees.emp_no=dept_emp.emp_no;

SQL7

查找薪水记录超过15次的员工号emp_no以及其对应的记录次数t

根据题目要求,分析可得使用分组函数 count() 和分组子句 group by,分组子句将员工号相同的放在一个集合中,count() 只统计非空字段,再用一个having 子句对分组后的结果进行过滤,条件是 COUNT(emp_no) > 15

SELECT emp_no, COUNT(emp_no) AS t
    FROM salaries
    GROUP BY emp_no
    HAVING COUNT(emp_no) > 15;

SQL8

找出所有员工具体的薪水salary情况,对于相同的薪水只显示一次,并按照逆序显示

distinct 关键字的作用是去重,order by 字段 desc 是降序显示

SELECT DISTINCT salary from salaries
    ORDER BY salary DESC;

SQL10

找出所有非部门领导的员工emp_no

先查询出 dept_manager 表中的所有员工,再从 employees 的表中筛选员工不在 dept_manager 中的记录

SELECT employees.emp_no 
    FROM employees
    WHERE employees.emp_no NOT IN(
    SELECT emp_no FROM dept_manager
    );

使用左外连接将两张表利用 emp_no 作为桥梁连接起来,where 子句过滤出没有部门号的员工

SELECT employees.emp_no 
    FROM employees LEFT JOIN dept_manager
    ON employees.emp_no = dept_manager.emp_no
    WHERE dept_manager.dept_no IS NULL;

SQL11

获取所有的员工和员工对应的经理,如果员工本身是经理的话则不显示

分析:在同一个部门里的员工和经理,他们的部门号是相同的;员工有两种可能的身份,不是员工,就是经理,所以 where 子句过滤掉员工本身是经理的情况

SELECT dept_emp.emp_no AS emp_no, dept_manager.emp_no AS manager
    FROM dept_emp LEFT JOIN dept_manager
    ON dept_emp.dept_no = dept_manager.dept_no
    WHERE dept_emp.emp_no  !=  dept_manager.emp_no;

SQL12 (困难)

获取每个部门中当前员工薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary,按照部门编号升序排列

这道题我刚开始只考虑到每个部门的最高薪水,忽略了员工包含于部门并且一个部门中薪水最高的员工可能不止一个,导致自测运行成功,但是在提交代码时报错,显示测试用例未通过。然后我先自己思考了一会儿,未果。之后我就开始在网上搜查发现了一个博主写的关于这道题的解析,思路清晰,令我豁然开朗。
解题步骤如下:
1、按照部门分组并生序排序(丢失了员工信息),获取每个部门的编号和最高薪水

#按照部门分组并生序排序(丢失了员工信息),获取每个部门的编号和最高薪水
SELECT d.dept_no, MAX(salary) AS max_salary
	FROM dept_emp d LEFT JOIN salaries s
	ON d.emp_no = s.emp_no
	GROUP BY dept_no
	ORDER BY dept_no

在这里插入图片描述
2、按照员工分组(没有部门信息),获取每个员工的编号和最高薪水

#按照员工分组(没有部门信息),获取每个员工的编号和最高薪水
SELECT d.emp_no, d.dept_no, s.salary
	FROM dept_emp d LEFT JOIN salaries s
	ON d.emp_no = s.emp_no

在这里插入图片描述
3、连接两张表,结合题目要求进行条件限定,取出相关结果集

#连接两张表,结合题目要求进行条件限定,取出相关结果集
SELECT r1.dept_no, r2.emp_no, r2.salary AS maxsalary FROM (
SELECT d.dept_no, MAX(salary) AS max_salary
	FROM dept_emp d LEFT JOIN salaries s
	ON d.emp_no = s.emp_no
	GROUP BY dept_no
	ORDER BY dept_no) AS r1
LEFT JOIN(
SELECT d.emp_no, d.dept_no, s.salary
	FROM dept_emp d LEFT JOIN salaries s
	ON d.emp_no = s.emp_no) AS r2
ON r1.dept_no = r2.dept_no AND r1.max_salary = r2.salary
ORDER BY r1.dept_no

在这里插入图片描述
好了,今天的SQL练习就到这里了,接下来我会继续在这里分享我的SQL练习历程,加油,坚持就是胜利!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值