目录

  • 11. 获取所有员工当前的manager,如果当前的manager是自己的话结果不显示,当前表示to_date='9999-01-01'。
  • 12. 获取所有部门中当前员工薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary
  • 13. 从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t
  • 14. 从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。
  • 15. 查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列
  • 16. 统计出当前各个title类型对应的员工当前薪水对应的平均工资。结果给出title以及平均工资avg。
  • 17. 获取当前(to_date='9999-01-01')薪水第二多的员工的emp_no以及其对应的薪水salary
  • 18. 查找当前薪水(to_date='9999-01-01')排名第二多的员工编号emp_no、薪水salary、last_name以及first_name,不准使用order by
  • 19. 查找所有员工的last_name和first_name以及对应的dept_name,也包括暂时没有分配部门的员工
  • 20. 查找员工编号emp_no为10001其自入职以来的薪水salary涨幅值growth
  • 完整的个人练习代码

11. 获取所有员工当前的manager,如果当前的manager是自己的话结果不显示,当前表示to_date='9999-01-01'。

结果第一列给出当前员工的emp_no,第二列给出其manager对应的manager_no

-- dept_emp部门员工表找到员工emp_no对应的部门dept_no, dept_manager部门管理表再找到管理者emp_no
SELECT de.emp_no, dm.emp_no AS manager_no
FROM dept_emp AS de, dept_manager AS dm
WHERE de.emp_no!=dm.emp_no AND dm.dept_no=de.dept_no
AND de.to_date="9999-01-01" AND dm.to_date="9999-01-01";

运行时间:30ms

占用内存:3464k

-- 使用内连接INNER JOIN关联部门员工表和管理员表
SELECT de.emp_no, dm.emp_no AS manager_no
FROM dept_emp AS de
INNER JOIN dept_manager AS dm
ON dm.dept_no=de.dept_no
WHERE de.emp_no!=dm.emp_no
AND de.to_date="9999-01-01" AND dm.to_date="9999-01-01";

运行时间:16ms

占用内存:3344k

12. 获取所有部门中当前员工薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary

当前(to_date="9999-01-01")各部门薪水最高员工
注意:该题目和审核系统是有坑的...

SELECT re1.dept_no, re2.emp_no, re1.salary
FROM (-- 先找出各部门最高薪水值 通过部门编号分组SELECT dept_em.dept_no, MAX(em_sa.salary) AS salaryFROM (SELECT emp_no, salaryFROM salariesWHERE to_date = '9999-01-01') AS em_saLEFT JOIN (SELECT emp_no, dept_noFROM dept_empWHERE to_date = '9999-01-01') AS dept_em ON em_sa.emp_no = dept_em.emp_noGROUP BY dept_no) re1
JOIN (-- 再找出各部门员工的薪水值 通过左连接SELECT dept_em.dept_no, em_sa.emp_no, em_sa.salary AS salaryFROM (SELECT emp_no, salaryFROM salariesWHERE to_date = '9999-01-01') AS em_saLEFT JOIN (SELECT emp_no, dept_noFROM dept_empWHERE to_date = '9999-01-01') AS dept_em ON em_sa.emp_no = dept_em.emp_no) re2
-- 通过连接获得最高薪水值对应的员工编号
ON re1.dept_no = re2.dept_no AND re1.salary = re2.salary
ORDER BY re1.dept_no;

运行时间:20ms

占用内存:5076k

  • 分析SQL代码:
    第一种解法: 6.67's
-- 通过to_date缩减需要选取的数据
-- 当前salaries表的emp_no和salary
SELECT emp_no, salary FROM salaries WHERE to_date='9999-01-01';
-- 当前dept_emp表的dept_no和emp_no
SELECT dept_no, emp_no FROM dept_emp WHERE to_date='9999-01-01';
-- 通过部门编号分组, 当前各部门的最高薪水salary和部门编号dept_no
SELECT dm.dept_no, MAX(se.salary) salary
FROM ((SELECT emp_no, salary FROM salaries WHERE to_date='9999-01-01') AS seLEFT JOIN(SELECT dept_no, emp_no FROM dept_emp WHERE to_date='9999-01-01') AS dmON se.emp_no=dm.emp_no)
GROUP BY dm.dept_no;
-- 无需分组, 将部门/员工/薪水合并到一个表内
SELECT dm.dept_no, dm.emp_no, se.salary
FROM ((SELECT emp_no, salary FROM salaries WHERE to_date='9999-01-01') AS seLEFT JOIN(SELECT dept_no, emp_no FROM dept_emp WHERE to_date='9999-01-01') AS dmON se.emp_no=dm.emp_no);
-- 通过`部门/最高薪水`的条件 去筛选/定位 `员工编号`
SELECT re1.dept_no, re2.emp_no, re1.salary
FROM (SELECT dm.dept_no, MAX(se.salary) salaryFROM ((SELECT emp_no, salary FROM salaries WHERE to_date='9999-01-01') AS seLEFT JOIN(SELECT dept_no, emp_no FROM dept_emp WHERE to_date='9999-01-01') AS dmON se.emp_no=dm.emp_no)GROUP BY dm.dept_no
) AS re1 JOIN (SELECT dm.dept_no, dm.emp_no, se.salaryFROM ((SELECT emp_no, salary FROM salaries WHERE to_date='9999-01-01') AS seLEFT JOIN(SELECT dept_no, emp_no FROM dept_emp WHERE to_date='9999-01-01') AS dmON se.emp_no=dm.emp_no)
) AS re2
ON re2.dept_no=re1.dept_no AND re2.salary=re1.salary
ORDER BY re1.dept_no;

第二种解法: 5.93's 结果是一样的,但无法通过牛客的审核

SELECT de.dept_no,sa.emp_no,re.sal AS salary
FROM (-- 通过分组,拿到各部门编号以及对应的最高薪水SELECT d.dept_no, MAX(s.salary) AS salFROM dept_emp AS d JOIN salaries AS sON d.emp_no=s.emp_no AND d.to_date='9999-01-01' AND s.to_date='9999-01-01'GROUP BY d.dept_no
) AS re, dept_emp AS de, salaries AS sa
-- 三表查询 re的最高薪水 部门员工表的部门编号 薪水表的员工编号
WHERE re.dept_no=de.dept_no AND de.emp_no=sa.emp_no AND re.sal=sa.salary;

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

SELECT title, COUNT(title) AS t FROM titles GROUP BY title HAVING t >= 2;

运行时间:18ms

占用内存:3424k

  • 注意:where和having的不同之处在于,where是查找之前的限定,而having是查找之后

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

注意对于重复的emp_no进行忽略

-- 统计拥有相同 title 的不同员工的个数 distinct可以放入函数体内
SELECT title, COUNT(DISTINCT emp_no) AS t FROM titles GROUP BY title HAVING t >= 2;

运行时间:17ms

占用内存:3300k

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

-- 判断属性奇偶数 1)取余 2)除与2再乘与2 3)位运算
SELECT * FROM employees WHERE emp_no%2=1 AND last_name!='Mary' ORDER BY hire_date DESC;

运行时间:20ms

占用内存:3400k

mysql判断奇数偶数,并思考效率

16. 统计出当前各个title类型对应的员工当前薪水对应的平均工资。结果给出title以及平均工资avg。

-- 注意avg是sql语法的关键字,需要``对其进行标注
SELECT t.title, AVG(s.salary) AS `avg` FROM titles AS t INNER JOIN salaries AS s ON s.emp_no=t.emp_no AND s.to_date='9999-01-01' AND t.to_date='9999-01-01' GROUP BY title;

运行时间:28ms

占用内存:3404k

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

-- 将salaries表按薪水salary逆序排列,再选取第二位
SELECT emp_no, salary FROM salaries WHERE to_date='9999-01-01' ORDER BY salary DESC LIMIT 1,1;

运行时间:22ms

占用内存:3320k

-- 以上方法是有缺陷的,题意是指薪水第二多,而同一薪水可能有多名员工
-- 先求出当前第二多薪水数额(distinct和group by都可以)
SELECT DISTINCT salary FROM salaries WHERE to_date='9999-01-01' ORDER BY salary DESC LIMIT 1,1;
SELECT salary FROM salaries WHERE to_date='9999-01-01' GROUP BY salary ORDER BY salary DESC LIMIT 1,1;
-- 再通过当前时间和薪水数额定位员工编号
SELECT emp_no, salary FROM salaries WHERE salary = (SELECT DISTINCT salary FROM salaries WHERE to_date='9999-01-01' ORDER BY salary DESC LIMIT 1,1
) AND to_date='9999-01-01';

运行时间:22ms

占用内存:3552k

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

-- 先找出当前最多薪水数额
SELECT MAX(salary) FROM salaries WHERE to_date='9999-01-01';
-- 使用排除法,在去掉最大值的序列中,此时最大值就原序列的第二大值
SELECT MAX(salary) FROM salaries
WHERE to_date='9999-01-01' AND salary NOT IN (SELECT MAX(salary)  FROM salaries WHERE to_date='9999-01-01'
);
-- 使用以上求取得到的第二大值
SELECT s.emp_no, s.salary, e.last_name, e.first_name
FROM salaries AS s INNER JOIN employees AS e ON s.emp_no=e.emp_no
WHERE s.to_date='9999-01-01'
AND s.salary = (SELECT MAX(salary) FROM salaries WHERE to_date='9999-01-01' AND salary NOT IN (SELECT MAX(salary)  FROM salaries WHERE to_date='9999-01-01')
);

运行时间:24ms

占用内存:3304k

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

-- 先将员工表employees和部门员工表dept_emp连接 合成部门员工详细表ds
SELECT e.emp_no, de.dept_no FROM employees AS e LEFT JOIN dept_emp AS de ON e.emp_no=de.emp_no;
-- 再将部门信息表department和部门员工详细表ds连接
SELECT ds.last_name, ds.first_name, d.dept_name FROM (SELECT e.last_name, e.first_name, de.dept_no FROM employees AS e LEFT JOIN dept_emp AS de ON e.emp_no=de.emp_no
) AS ds LEFT JOIN departments AS d ON d.dept_no=ds.dept_no;

运行时间:18ms

占用内存:3312k

-- 第一次 left join 是把未分配部门的员工算进去了,但是只得到了部门编号dept_no,没有部门名dept_name,
-- 所以第二次也要 left join 把含有部门名 departments表 连接起来,
-- 否则在第二次连接时就选不上未分配部门的员工了
SELECT e.last_name, e.first_name, d.dept_name
FROM employees AS e
LEFT JOIN dept_emp AS de ON e.emp_no = de.emp_no
LEFT JOIN departments AS d ON de.dept_no = d.dept_no;

运行时间:20ms

占用内存:3404k

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

个人理解为:获得入职时的工资距离最新的工资的涨幅情况

-- 最大值-最小值 这种解法是有问题的 其是以薪水一直在涨/上升的前提下
SELECT (MAX(salary)-MIN(salary)) AS growth FROM salaries WHERE emp_no='10001';

运行时间:19ms

占用内存:3424k

-- 薪水salary涨幅值growth 当前薪水-入职薪水
SELECT (ma.salary-mi.salary) AS growth
FROM (-- 入职薪水SELECT salary FROM salaries WHERE emp_no='10001' ORDER BY to_date LIMIT 0,1
) AS mi, (-- 当前薪水SELECT salary FROM salaries WHERE emp_no='10001' ORDER BY to_date DESC LIMIT 0,1
) AS ma;

运行时间:21ms

占用内存:3688k

完整的个人练习代码

我的练习SQL代码已经上传至Github:https://github.com/slowbirdoflsh/newcode-sql-practice
仅供参考~~~

转载于:https://www.cnblogs.com/slowbirdoflsh/p/11210684.html

[牛客数据库SQL实战] 11~20题及个人解答相关推荐

  1. 牛客数据库SQL实战 51-60(substr切割字符串、group_concat组拼接、limit_offset分页、exists条件成立判断、case分支、表的复用)

    文章目录 51* 获取Employees中的first_name 51.1 题目描述 51.2 题解 substr 52* 按照dept_no进行汇总 52.1 题目描述 52.2 题解 group_ ...

  2. 牛客 数据库SQL实战 将titles_test表名修改为titles_2017

    题目描述:\color{blue}题目描述:题目描述: 将titles_test表名修改为titles_2017. CREATE TABLE IF NOT EXISTS titles_test ( i ...

  3. 牛客 数据库SQL实战 将所有获取奖金的员工当前的薪水增加10%

    题目描述:\color{blue}题目描述:题目描述: 将所有获取奖金的员工当前的薪水增加10%. create table emp_bonus( emp_no int not null, recev ...

  4. 牛客 数据库SQL实战 获取员工其当前的薪水比其manager当前薪水还高的相关信息

    题目描述:\color{blue}题目描述:题目描述: 获取员工其当前的薪水比其manager当前薪水还高的相关信息,当前表示to_date='9999-01-01', 结果第一列给出员工的emp_n ...

  5. 牛客网数据开发题库_练习SQL利器,牛客网SQL实战题库

    牛客网SQL实战网址:https://www.nowcoder.com/ta/sql 持续更新--记录自己在牛客网SQL的做题过程 更新进度:61题,2019-4-3,更完了 1.查找最晚入职员工的所 ...

  6. 牛客网SQL实战二刷 | Day10

    「牛客网SQL实战二刷」是个系列学习笔记博文,今天解析7道SQL题目- 第55 - 61题. 每篇笔记的格式大致为,三大板块: 大纲 题目(题目描述.思路.代码.相关参考资料/答疑) 回顾 ❤️「往期 ...

  7. 牛客网SQL实战二刷 | Day2

    「牛客网SQL实战二刷」是个系列学习笔记博文,每天解析6道SQL题目- 今天是第7-12 题!该系列的其他博文,可在「我的博客」 中查看- 每篇笔记的格式大致为,三大板块: 大纲 题目(题目描述.思路 ...

  8. 牛客网SQL实战二刷 | 完整解析 -- 目录索引

    「牛客网SQL实战二刷」是个系列学习笔记博文,Day1 - Day10,每天解析6道SQL题目- 初衷是留给自己一份笔记,也希望能分享给「一起学习SQL的你」? 每篇笔记的格式大致为,三大板块: 大纲 ...

  9. 牛客网SQL 进阶篇刷题

    牛客网SQL 进阶篇刷题(1-19) 用户1001在2021年9月1日晚上10点11分12秒开始作答试卷9001,并在50分钟后提交,得了90分: 用户1002在2021年9月4日上午7点1分2秒开始 ...

最新文章

  1. 怎么学python-如何轻松学习Python数据分析
  2. Java 查找指定类型的数组元素
  3. 【java基础】zip压缩文件
  4. django 学习 (二) 模板
  5. 华南理工大学广州学院计算机二级,华南理工大学广州学院学子在第三届“泰迪杯”数据分析职业技能大赛中荣获佳绩...
  6. 中大型计算机代表型号,目前个人计算机主要机型.doc
  7. 软件测试面试技巧|项目常识篇
  8. kafka 修改分区_kafka修改分区和副本数
  9. python环境的打包与加载
  10. 【知了堂学习笔记】java 自定义异常
  11. 用python实现搜索树_二叉搜索树的python实现
  12. 南京邮电大学c语言实验报告4,南京邮电大学软件设计实验报告..doc
  13. Android之制作Nine-Patch图片
  14. 数字逻辑练习题(四)用卡诺图化简下面的函数为最简“与-或”式
  15. 复利,世界第八大奇迹
  16. 远程拨号换IP的方法
  17. 「LSTM 之父」亲笔万字长文,只为向世人证明:深度学习不是在母语为英语的地方被发明的...
  18. Excel2003创建表格首行冻结
  19. 安卓作业—Fragment界面跳转
  20. 运动世界校园 校园跑 不想跑步人的福利

热门文章

  1. 统一并发 IV——走向跨平台
  2. MySQL8的8大新SQL特性
  3. 消费和部署ASP.NET WebApi服务–陷阱
  4. Firefox 和 Chrome 性能测试对比
  5. esd文件转换成gho文件_STL到OBJ:如何将STL文件转换成OBJ ?
  6. python如何制作一个任意列表_在Python中扁平化任意嵌套列表的最快方法是什么?...
  7. flowable 中文文档_取出word文档文字内容生成加了目录、标号和页码的PDF文件
  8. 简易 Vue 构建--篇三
  9. python web 文件管理_我的第一个python web开发框架(23)——代码版本控制管理与接口文档...
  10. python怎样编写姓名、职业、地址_如何根据姓名、地址识别人际关系,然后通过linux comman或Pysp分配相同的ID...