「牛客网SQL实战二刷」是个系列学习笔记博文,今天解析7道SQL题目~ 第55 - 61题。

每篇笔记的格式大致为,三大板块:

  • 大纲
  • 题目(题目描述、思路、代码、相关参考资料/答疑)
  • 回顾

❤️「往期回顾」

《牛客网SQL实战二刷 | 完整解析 – 目录索引》


一、大纲

题号 知识点
55 LIMIT,OFFSET
56 LEFT JOIN
57 NOT EXISTS
58 求交集
59 CASE WHEN
60 表复用计算累加和
61 表复用计算行数

二、题目

55. 分页查询employees表,每5行一页,返回第2页的数据

  • 题目描述

分页查询employees表,每5行一页,返回第2页的数据

CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));
  • 思路

转化一下题意,「每5行一页,返回第2页的数据」,即返回第6~10条记录,用LIMIT 搭配 OFFSET 使用。

  • 代码
SELECT * FROM employees LIMIT 5 OFFSET 5;

?Limit 与offset

举个例子,LIMIT 3 OFFSET 1, 这意味着,跳过第1条记录(即从第2条记录开始),返回接下来3条记录。即最终得到,原本的第2,3,4条记录。

  • 举一反三

《牛客网SQL实战二刷 | Day1》第2题。

  • 参考资料

《SQLite Limit 子句》https://www.runoob.com/sqlite/sqlite-limit-clause.html


56. 获取所有员工的emp_no

  • 题目描述

获取所有员工的emp_no、部门编号dept_no以及对应的bonus类型btype和recevied,没有分配具体的员工不显示

CREATE TABLE `dept_emp` ( `emp_no` int(11) NOT NULL,
`dept_no` char(4) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));create table emp_bonus(
emp_no int not null,
recevied datetime not null,
btype smallint not null);
  • 输出描述
e.emp_no dept_no btype recevied
10001 d001 1 2010-01-01
10002 d001 2 2010-10-01
10003 d004 3 2011-12-03
10004 d004 1 2010-01-01
10005 d003
10006 d002
10007 d005
10008 d005
10009 d006
  • 思路

表dept_emp 左连接 表emp_bonus。

  • 代码
SELECT de.emp_no, de.dept_no, eb.btype, eb.recevied
FROM dept_emp AS de LEFT JOIN emp_bonus AS eb ON
de.emp_no = eb.emp_no;

57. 使用含有关键字exists查找未分配具体部门的员工的所有信息。

  • 题目描述

使用含有关键字exists查找未分配具体部门的员工的所有信息。

CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));
CREATE TABLE `dept_emp` (
`emp_no` int(11) NOT NULL,
`dept_no` char(4) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
  • 输出描述
emp_no birth_date first_name last_name gender hire_date
10011 1953-11-07 Mary Sluis F 1990-01-22
  • 思路
  • 本题用 EXISTS 关键字的方法如下:意为在 employees 中挑选出令(SELECT emp_no FROM dept_emp WHERE emp_no = employees.emp_no)不成立的记录,也就是当 employees.emp_no=10011的时候。反之,把NOT去掉,则输出 employees.emp_no=10001~10010时的记录。
  • 由于 OJ系统没有限制我们只能使用 EXISTS 关键字,因此还能用 NOT IN 关键字替换,即在employees 中选出 dept_emp 中没有的 emp_no。

作者:wasrehpic
来源:https://www.nowcoder.com/questionTerminal/c39cbfbd111a4d92b221acec1c7c1484?f=discussion

  • 代码
  1. 方法一、NOT EXISTS
SELECT * FROM employees
WHERE NOT EXISTS (SELECT emp_no FROM dept_emp WHERE emp_no = employees.emp_no)
  1. 方法二、NOT IN
SELECT * FROM employees
WHERE emp_no NOT IN (SELECT emp_no FROM dept_emp)

58. 获取employees中的行数据,且这些行也存在于emp_v中

  • 题目描述

存在如下的视图:

create view emp_v as select * from employees where emp_no >10005;
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));

获取employees中的行数据,且这些行也存在于emp_v中。注意不能使用intersect关键字。

  • 输出描述
emp_no birth_date first_name last_name gender hire_date
10006 1953-04-20 Anneke Preusig F 1989-06-02
10007 1957-05-23 Tzvetan Zielinski F 1989-02-10
10008 1958-02-19 Saniya Kalloufi M 1994-09-15
10009 1952-04-19 Sumant Peac F 1985-02-18
10010 1963-06-01 Duangkaew Piveteau F 1989-08-24
10011 1953-11-07 Mary Sluis F 1990-01-22
  • 思路

根据题意,不能使用 INTERSECT 关键字,但由于视图 emp_v 的记录是从 employees 中导出的,因此要判断两者中相等的数据,只需要判断emp_no相等即可。

  • 方法一:用 WHERE 选取二者 emp_no 相等的记录
  • 方法二:由于emp_v的全部记录均由 employees 导出,因此可以投机取巧,直接输出 emp_v 所有记录
  • 代码
  1. 方法一
SELECT em.* FROM employees AS em, emp_v AS ev WHERE em.emp_no = ev.emp_no;
  1. 方法二
SELECT * FROM emp_v;
  1. 方法三:OJ系统限制了,但是如果用INTERSECT实现
SELECT * FROM emp_v INTERSECT SELECT * FROM employees
  • 举一反三

《牛客网SQL实战二刷 | Day8》第47题。


59. 获取有奖金的员工相关信息。

  • 题目描述

获取有奖金的员工相关信息。

CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));CREATE TABLE `dept_emp` (
`emp_no` int(11) NOT NULL,
`dept_no` char(4) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
create table emp_bonus(
emp_no int not null,
recevied datetime not null,
btype smallint not null);CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL, PRIMARY KEY (`emp_no`,`from_date`));

给出emp_no、first_name、last_name、奖金类型btype、对应的当前薪水情况salary以及奖金金额bonus。 bonus类型btype为1其奖金为薪水salary的10%,btype为2其奖金为薪水的20%,其他类型均为薪水的30%。 当前薪水表示to_date=‘9999-01-01’

  • 思路

用CASE WHEN条件判断。

  • 输出描述
emp_no first_name last_name btype salary bonus
10001 Georgi Facello 1 88958 8895.8
10002 Bezalel Simmel 2 72527 14505.4
10003 Parto Bamford 3 43311 12993.3
10004 Chirstian Koblick 1 74057 7405.7
  • 代码
SELECT e.emp_no, e.first_name, e.last_name, eb.btype, s.salary,
(CASE eb.btypeWHEN 1 THEN 0.1 * s.salaryWHEN 2 THEN 0.2 * s.salaryELSE 0.3 * s.salary
END ) AS bonus
FROM employees AS e INNER JOIN emp_bonus AS eb ON e.emp_no = eb.emp_no
INNER JOIN salaries AS s ON e.emp_no = s.emp_no AND s.to_date = '9999-01-01'

?CASE WHEN

Case具有两种格式。简单Case函数和Case搜索函数。

--简单Case函数
SELECT  SUM(population), CASE (country  WHEN '中国' THEN '亚洲' WHEN '印度' THEN '亚洲' WHEN '日本' THEN '亚洲' WHEN '美国' THEN '北美洲' WHEN '加拿大'  THEN '北美洲' WHEN '墨西哥'  THEN '北美洲' ELSE '其他' END)
FROM    Table_A --Case搜索函数UPDATE Personnel
SET salary =
CASE (WHEN salary >= 5000  THEN salary * 0.9WHEN salary >= 2000 AND salary < 4600  THEN salary * 1.15ELSE salary END); 
-- 用一个SQL语句完成不同条件的分组SELECT country, SUM( CASE WHEN sex = '1' THEN  population ELSE 0 END),  --男性人口 SUM( CASE WHEN sex = '2' THEN  population ELSE 0 END)   --女性人口
FROM  Table_A  GROUP BY country;
  • 强烈参考

《【SQL】SQL中Case When的用法》https://www.cnblogs.com/HDK2016/p/8134802.html


?60. 统计salary的累计和running_total

  • 题目描述

按照salary的累计和running_total,其中running_total为前两个员工的salary累计和,其他以此类推。 具体结果如下Demo展示。。

CREATE TABLE `salaries` ( `emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));
  • 输出描述
emp_no salary running_total
10001 88958 88958
10002 72527 161485
10003 43311 204796
10004 74057 278853
10005 94692 373545
10006 43311 416856
10007 88070 504926
10009 95409 600335
10010 94409 694744
10011 25828 720572
  • 思路

复用 表salaries,限制s1的emp_no小于等于 s2的emp_no,再对s1的工资求和,即相当于累加。

  • 代码
SELECT s2.emp_no, s2.salary, SUM(s1.salary) AS running_total
FROM salaries AS s1 INNER JOIN salaries AS s2
ON s1.emp_no <= s2.emp_no
WHERE s1.to_date = '9999-01-01' AND s2.to_date = '9999-01-01'
GROUP BY s2.emp_no

?61. 对于employees表中,给出奇数行的first_name

  • 题目描述

对于employees表中,给出奇数行的first_name

CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));
  • 输出描述
first_name
Georgi
Chirstian
Anneke
Tzvetan
Saniya
Mary
  • 思路
  1. 和上一题相似的地方在于,也是表的复用,其实相当于我们自己写了语句计算row numbers;
  2. 「奇数行」,即行数除以2余1。
  • 代码
SELECT e1.first_name FROM employees AS e1
WHERE (SELECT COUNT(*) FROM employees AS e2WHERE e1.first_name <= e2.first_name)%2 == 1;

?SQLITE 创建rownumber

  1. 原表
  2. 插入rownumber 代码实现
SELECT( SELECT COUNT(distinct id)  FROM  [file] AS t2  WHERE t2.id <= t1.id) AS rowNum, id,  name FROM [file] t1 ORDER BY  t1.id asc
  1. 新表


来源:http://www.onbno.com/ruanjiajiqiao/sqlite-none-row-number.html

  • 强烈推荐

《sqlite没有行号(rownumber)的解决办法》 http://www.onbno.com/ruanjiajiqiao/sqlite-none-row-number.html


三、回顾

知识点 题号
LIMIT,OFFSET 55
表连接 56
NOT EXISTS 57
求交集 58
CASE WHEN 59
表复用 60,61

? 写在最后

Day10 是「牛客网SQL实战二刷」系列最后一天啦。坚持就是胜利,欧耶✌️

比起第一次做SQL题库,这次在前半部分查询语句的方面,明显进步很多。很多时候直接上手敲,就能通过了。不过,后半部分,大概从Day6开始,虽然代码变得短小和简单了,但是反而不那么熟悉,往往要辅助资料,也能敲出来。但我相信,这次「二刷题库」扎实了我的基础。

通过我做「真题」的体验,「数据库管理和操作」对「数据分析岗」真是非常非常非常关键和重要的了,是基础也是必须。真题里的SQL操作,结合上业务需要,比起题库里的题更具有应用性,比如「拼多多2020数据分析师真题」。我依旧有很多没见过的需求,我还有很多不会的和要掌握的。

可能还会三刷,可能接下来偏向分享「来源于真题中的,有业务背景的,对真实需求对数据库操作」。

牛客网SQL实战二刷 | Day10相关推荐

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

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

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

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

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

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

  4. 牛客网SQL 进阶篇刷题

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

  5. 查找最晚入职员工的所有信息---牛客网SQL实战篇

    查找入职员工时间排名倒数第三的员工所有信息 数据表 CREATE TABLE `employees` ( `emp_no` int(11) NOT NULL, `birth_date` date NO ...

  6. sql里查询一个组和组的用户数怎么查?_【牛客网SQL刷题】留存率怎么算?

    抽空刷了牛客网SQL实战72题,最后几道以牛客网为例的题目还挺有挑战性,在此记录 统计时间段新用户次日留存率 每日的次日留存率 每日的新用户数 每日新用户的次日留存 求新登录用户次日留存 表login ...

  7. 牛客网sql练习打卡

    目录 第一题 解题: 1.使用表的子连接 2.使用降序取第一个 第二题 解题: 1.降序取第三个 2.limit offset 3.子查询 2021/10/8 今天第一次开始尝试使用牛客网练习sql, ...

  8. 牛客网sql题库(1-30题)—— 个人答案与过程解析

    本篇博客分享一下我在牛客网sql题库刷题时,自己敲出来的结果.结果均通过了牛客网的结果验证. 具体的题目就不放在博客中了,感兴趣可以自行去搜索牛客网,找到sql题库在线编程 每道题下面都有我自己写的题 ...

  9. 牛客网SQL刷题笔记(MySQL)

    牛客网SQL刷题笔记(MySQL) 此博客集合LeetCode.牛客网常见的题型及其解法,侵删 目录 牛客网SQL刷题笔记(MySQL) 类型1:查找排名第几的数据 SQL2 查找入职员工时间排名倒数 ...

最新文章

  1. 【翻译】旧技术成就新勒索软件,Petya添加蠕虫特性
  2. Python_note5 函数和代码复用+PyInstaller库+数码管绘制
  3. 在安装one_gadget遇到 one_gadget requires Ruby version >= 2.4. 的问题解决
  4. Selenium IDE安装和检查获取的控件路径技巧
  5. 曹大带我学 Go(5)—— 哪里来的 goexit
  6. 手机客户端测试考虑的点
  7. torch.stack作用分析
  8. 2016下半年网络规划设计师考试下午真题
  9. 笑着学会Linux 系统之故障排查
  10. linux shell 学习时遇到的一些问题([: 11: y: unexpected operator)
  11. 无穷积分 ∫sinx/xdx 的几种巧妙解法
  12. 国外10个最佳和最流行的酷站推荐网站
  13. java求两点间的距离_java计算两点间的距离方法总结
  14. 什么是决策!决策的定义!决策的本质!大数据决策定义!
  15. 特征图注意力_【抠图中的注意力机制】HAttMatting---让抠图变得如此简单!
  16. 【机器视觉硬件】机器视觉硬件学习笔记2——工业相机
  17. 更改Anaconda下载源,提高下载速度
  18. PHP简单实现个人网站
  19. IOS开发 汉字转拼音 把用户名按照姓名首字母进行排序
  20. SuperMap GIS BIM类型数据处理 QA

热门文章

  1. VMware 7.0正式版
  2. cad和php哪个工资高,CAD顶级绘图员必备,人手一份的绘图命令,学会工资上万不是梦...
  3. 拂去ThreadLocal的轻纱
  4. ACM程序设计书中题目--J(大写字母的更替)
  5. 从语义网的角度看聊天机器人的产生
  6. 【华为OD机试真题 Python】加扰字符串
  7. Win10计算机窗口空白,Win10系统下启用或关闭windows功能打开后显示空白如何解决...
  8. 公网视频流访问之webrtc-streamer
  9. 【HEVC简介】CTU、CU、PU、TU结构
  10. ios-deploy 安装与使用