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

【题解】

hire_date可能存在重复值,所以需要找到hire_date的最大值,然后再筛选,才能hire_date最晚的记录都筛选出来。

【代码】

1 SELECT * FROM employees
2 WHERE hire_date = (SELECT MAX(hire_date) FROM employees)

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

【题解】

还是hire_date可能存在重复值问题,所以需要先找到第三晚的hire_date(此处排序记得用distinct去重),然后再进行筛选。

【代码】

1 SELECT * FROM employees
2 WHERE hire_date = (SELECT DISTINCT hire_date FROM employees
3 ORDER BY hire_date DESC LIMIT 2, 1)

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

【题解】

这题好坑哦,因为题目中说的是“薪水详情以及其对应部门编号dept_no”,所以salaries表是主表,要写在前面?(我对这个思路并不是很赞同)

但其实我觉得是后台没有排序问题,只要把emp_no排个序也能过。

【代码】

SELECT s.*, d.dept_no
FROM salaries s, dept_manager d
WHERE d.to_date = '9999-01-01' AND s.to_date = '9999-01-01' AND d.emp_no = s.emp_no
1 SELECT s.*, d.dept_no
2 FROM dept_manager d, salaries s
3 WHERE d.to_date = '9999-01-01' AND s.to_date = '9999-01-01' AND d.emp_no = s.emp_no
4 ORDER BY s.emp_no

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

【题解】

也就是说有的员工不一定被分配了部门,那么只要将部门表左连接到员工表,即部门表上的信息都会有,但部门表上没有员工表上有的信息就不会被筛出,符合题目所求。

【代码】

1 SELECT e.last_name, e.first_name, d.dept_no
2 FROM dept_emp d LEFT JOIN employees e ON e.emp_no = d.emp_no

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

【题解】

跟上一题刚好反一下,这里是要把员工表左连接到部门表,这样不管员工是否有对应的部门,都能被显示出来。

【代码】

1 SELECT e.last_name, e.first_name, d.dept_no
2 FROM employees e LEFT JOIN dept_emp d ON e.emp_no = d.emp_no

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

【题解】

这里需要注意一下,因为是给出每个员工入职时的薪资,所以还需要将加上这个条件e.hire_date = s.from_date。

【代码】

1 SELECT e.emp_no, s.salary
2 FROM employees e, salaries s
3 WHERE e.emp_no = s.emp_no AND e.hire_date = s.from_date
4 ORDER BY e.emp_no DESC

7、查找薪水涨幅超过15次的员工号emp_no以及其对应的涨幅次数t

【题解】

GROUP BY配合聚合函数使用,按照emp_no分类后,COUNT记录每个emp_no的薪水涨幅次数,最后选出大于15的即可。

COUNT语句后面要跟HAVING哦。

如果对GROUP BY和聚合函数的使用不是很了解的话可以戳这里,我感觉讲的蛮好的。

【代码】

1 SELECT emp_no, COUNT(to_date) AS t
2 FROM salaries GROUP BY emp_no HAVING t > 15

8、找出所有员工当前薪水salary情况

【题解】

DISTINCT:如果作用于某一列,同一列的相同值只会出现一次,如果作用于所有列,那么所有列的相同值都相同才相同(可用于整张表去重)。

ORDER BY:ORDER BY col DESC 按照col列降序排,ASC为升序。

【代码】

1 SELECT DISTINCT salary
2 FROM salaries WHERE to_date = '9999-01-01'
3 ORDER BY salary DESC

9、获取所有部门当前manager的当前薪水情况

【题解】

类似第3题

【代码】

1 SELECT d.dept_no, d.emp_no, s.salary
2 FROM dept_manager d, salaries s
3 WHERE d.emp_no = s.emp_no AND d.to_date = '9999-01-01' AND s.to_date = '9999-01-01'

10、获取所有非manager的员工emp_no

【题解】

使用NOT IN选出在employees但不在dept_manager中的emp_no记录,NOT IN的话就是顾名思义啦,“不在”的意思。

【代码】

1 SELECT e.emp_no FROM employees e
2 WHERE emp_no NOT IN(SELECT d.emp_no FROM dept_manager d)

11、获取所有员工当前的manager

【题解】

题意中明确说明如果是manager自己的话不用显示,所以需要加上这一句e.emp_no != m.emp_no,然后按要求连接两张表查询就可以啦。

【代码】

1 SELECT e.emp_no, m.emp_no AS manager_no
2 FROM dept_emp e, dept_manager m
3 WHERE e.dept_no = m.dept_no AND e.to_date = '9999-01-01'
4 AND m.to_date = '9999-01-01' AND e.emp_no != m.emp_no

12、获取所有部门中当前员工薪水最高的相关信息

【题解】

可以通过两步来理解。

第一步:通过emp_no将两个表连接,并挑选出所有部门当前员工工薪,当前是9999-01-01,题里没说,是个小bug。

第二步:因为需要给出所有部门中工薪最高的信息,所以我们按照部门分组,将最高的工薪选出来。

【代码】

1 SELECT d.dept_no, d.emp_no, s.salary
2 FROM dept_emp d, salaries s
3 WHERE d.emp_no = s.emp_no AND d.to_date = '9999-01-01' AND s.to_date = '9999-01-01'
4 GROUP BY d.dept_no HAVING MAX(s.salary)

13、从titles表获取按照title进行分组

【题解】

第一步:根据title将表进行分组

第二步:分组后将具有相同title的记录计数,返回>=2的即可。

【代码】

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

14、从titles表获取按照title进行分组,注意对于重复的emp_no进行忽略。

【题解】

这题首先要理解清楚题目的意思,题意是想我们找到按照title分组后,每组个数大于等于2(并且其中不能包含重复的emp_no)

比如title emp_no

1      1

1       1

这样的COUNT只能算1个哦。所以还是分2步走。

第一步:按照title分组

第二步:利用DISTINCT去掉重复emp_no,然后计数。

【代码】

1 SELECT title, COUNT(DISTINCT emp_no) AS t
2 FROM titles
3 GROUP BY title HAVING t >= 2

15、查找employees表

【题解】

这题比较简单,直接按题意做就可以啦。

【代码】

1 SELECT * FROM employees
2 WHERE emp_no % 2 = 1 AND last_name != 'Mary'
3 ORDER BY hire_date DESC

16、统计出当前各个title类型对应的员工当前薪水对应的平均工资

【题解】

还是分2步来理解。

第一步:先通过emp_no将两个表连接

第二步:按照title分组,并对同属一个title的salay进行avg运算。

【代码】

1 SELECT t.title, AVG(s.salary) AS avg
2 FROM titles t, salaries s
3 WHERE t.emp_no = s.emp_no AND t.to_date = '9999-01-01' AND s.to_date = '9999-01-01'
4 GROUP BY t.title

17、获取当前薪水第二多的员工的emp_no以及其对应的薪水salary

【题解】

类似第二题

【代码】

1 SELECT emp_no, salary FROM salaries
2 WHERE to_date = '9999-01-01' AND salary = (
3 SELECT DISTINCT salary FROM salaries
4 ORDER BY salary DESC LIMIT 1, 1
5 )

18、获取当前薪水第二多的员工的emp_no以及其对应的薪水salary,不准使用order by

【题解】

仍然2步走。

第一步:先把两个表通过emp_no连接起来

第二步:因为这里不能用ORDER BY,所以不能再用上面的方法了,我们可以这么想,我先找出一个最大值salary,然后再找比这个最大值小的最大值,那不就是次大值了吗?

然后这里要注意题意是说当前薪水第二多的员工,所以只需s.to_date = '9999-01-01'即可。

【代码】

1 SELECT e.emp_no, MAX(s.salary), e.last_name, e.first_name
2 FROM employees e, salaries s
3 WHERE s.salary < (SELECT MAX(salary) FROM salaries
4 WHERE to_date = '9999-01-01')
5 AND e.emp_no = s.emp_no AND s.to_date = '9999-01-01'

19、查找所有员工的last_name和first_name以及对应的dept_name

【题解】

第一步:将employees表和dept_emp表通过emp_no进行左外连接,这样不管有没有分配部门的员工号对应的部门号就找出来了。

第二步:用同样的方法就讲dept_emp和departments左外连接,就能得到答案啦。

【代码】

1 SELECT e.last_name, e.first_name, dp.dept_name
2 FROM (employees e LEFT JOIN dept_emp d ON e.emp_no = d.emp_no)
3 LEFT JOIN departments dp ON d.dept_no = dp.dept_no

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

【题解】

涨幅值即薪水的最大值 - 最小值,知道这个就可以做啦。

【代码】

1 SELECT (MAX(salary) - MIN(salary)) AS growth
2 FROM salaries WHERE emp_no = '10001'

21、查找所有员工自入职以来的薪水涨幅情况

【题解】

做到这题的时候会发现,这次要求的时候所有盐工自入职以来的薪水涨幅情况,所以我们可以新建两张表。

一张是当前员工的薪水,一张是员工入职时的薪水,再将两张表连接一下排序就可以了。

【代码】

1 SELECT now.emp_no, (now.salary - pre.salary) AS growth
2 FROM (SELECT e.emp_no, s.salary FROM employees e, salaries s
3 WHERE e.emp_no = s.emp_no AND s.to_date = '9999-01-01') AS now,
4 (SELECT e.emp_no, s.salary FROM employees e, salaries s
5 WHERE e.emp_no = s.emp_no AND e.hire_date = s.from_date) AS pre
6 WHERE now.emp_no = pre.emp_no
7 ORDER BY growth ASC

22、统计各个部门对应员工涨幅的次数总和

【题解】

将三个表连接后,按照dept_no分组,计算有几条salary记录即可。

【代码】

1 SELECT dp.dept_no, dp.dept_name, COUNT(s.salary) AS sum
2 FROM departments dp, dept_emp d, salaries s
3 WHERE dp.dept_no = d.dept_no AND d.emp_no = s.emp_no
4 GROUP BY dp.dept_no

23、对所有员工的薪水按照salary进行按照1-N的排名

【题解】

这道题我觉得还是挺巧妙的,有必要收藏一下嘻嘻嘻。

首先要将两张salaries表连接,先挑选出to_date = '9999-01-01'的记录,然后注入灵魂的一句话就是s1.salary <= s2.salary,这句话是什么意思呢?比如我在s1表中找到一个salary是100,在s2中就能找到对应的大于等于100的(100,100,300)这样3条数据,然后用DISTINCT去重之后也就是2条,就是该salary的排名啦。

【代码】

1 SELECT s1.emp_no, s1.salary, COUNT(DISTINCT s2.salary) AS rank
2 FROM salaries s1, salaries s2
3 WHERE s1.to_date = '9999-01-01' AND s2.to_date = '9999-01-01' AND s1.salary <= s2.salary
4 GROUP BY s1.emp_no
5 ORDER BY s1.salary DESC, s1.emp_no ASC

24、获取所有非manager员工当前的薪水情况

【题解】

好像斌不需要用employees表?

因为我只需从salaries表中找出不属于dept_manager表的emp_no,然后让salaries表和dept_emp连接就可以得到非manager员工当前的薪水情况啦。

【代码】

1 SELECT d.dept_no, s.emp_no, s.salary
2 FROM dept_emp d, salaries s
3 WHERE s.emp_no NOT IN (SELECT emp_no FROM dept_manager) AND
4 s.emp_no = d.emp_no AND s.to_date = '9999-01-01'

25、获取员工其当前的薪水比其manager当前薪水还高的相关信息

【题解】

首先将manager表和salaries表连接成一个新表ms,emp表和salaries表也连接成一个新表es。

然后就可以根据题意操作啦,只要es.salary > ms.salary就可以了。

【代码】

1 SELECT es.emp_no, ms.emp_no AS manager_no, es.salary AS emp_salary, ms.salary AS manager_salary
2 FROM (dept_emp AS d INNER JOIN salaries AS s ON d.emp_no = s.emp_no AND s.to_date = '9999-01-01')AS es,
3 (dept_manager AS dm INNER JOIN salaries AS s ON dm.emp_no = s.emp_no AND s.to_date = '9999-01-01')AS ms
4 WHERE es.emp_no NOT IN (SELECT emp_no FROM dept_manager) AND
5 es.dept_no = ms.dept_no AND es.salary > ms.salary

26、汇总各个部门当前员工的title类型的分配数目

【题解】

这里有几个注意点。

(1)这里统计的是当前员工的当前头衔,所以t.to_date = '9999-01-01',d.to_date = '9999-01-01'

(2)分组也有两个参数,因为首先需要根据部门分组,再在部门里面根据不同的title进行分组统计。

【代码】

1 SELECT d.dept_no, dp.dept_name, t.title, COUNT(t.title) AS count
2 FROM departments dp, dept_emp d, titles t
3 WHERE dp.dept_no = d.dept_no AND d.emp_no = t.emp_no AND t.to_date = '9999-01-01'
4 AND d.to_date = '9999-01-01'
5 GROUP BY d.dept_no, t.title

27、给出每个员工每年薪水涨幅超过5000的员工编号emp_no

【题解】

设s1表为员工涨薪之前的表,s2表为员工涨薪之后的表。那么通过emp_no就可以把他们连接起来。然后这道题其实题意不是很明确,他说是每年,但事实上只要年份差为1即可。

因此只需要两个表的to_date相差1,且满足薪水涨幅超过5000就要把它选出来,另外不能忘记如果两个表的from_date相差1,也是需要被选出来的。比如有两个字段(2000-5-05,2001-6-13)和(2001-7-30,2001-8-12)也可以算是相差1年。

【代码】

1 SELECT s2.emp_no, s2.from_date, (s2.salary - s1.salary) AS salary_growth
2 FROM salaries s1, salaries s2
3 WHERE s1.emp_no = s2.emp_no
4 AND salary_growth > 5000
5 AND (strftime("%Y", s2.to_date) - strftime("%Y", s1.to_date) = 1
6 OR strftime("%Y", s2.from_date) - strftime("%Y", s1.from_date) = 1 )
7 ORDER BY salary_growth DESC

28、查找描述信息中包括robot的电影对应的分类名称以及电影数目,而且还需要该分类对应电影数量

【题解】

这题我们可以把每个类别电影数目>=5的类别先找出来建立个虚表cc。

然后经过这几个表的连接就可以得到答案啦。

【代码】

1 SELECT c.name, COUNT(fc.film_id) AS num
2 FROM (SELECT category_id FROM film_category
3 GROUP BY category_id HAVING COUNT(film_id) >=5) AS cc,
4 film f, category c, film_category fc
5 WHERE f.description LIKE '%robot%' AND f.film_id = fc.film_id
6 AND fc.category_id = cc.category_id AND fc.category_id = c.category_id

29、使用join查询方式找出没有分类的电影id以及名称

【题解】

这题还是蛮简单的,只需要通过左连接找到有分类的电影id,然后加个NOT IN就可以了。

【代码】

1 SELECT film_id, title
2 FROM film
3 WHERE film_id NOT IN(
4 SELECT f.film_id FROM film_category AS fc LEFT JOIN film AS f ON fc.film_id = f.film_id)

30、用子查询的方式找出属于Action分类的所有电影对应的title,description

【题解】

简单题,通过WHERE...IN...将3张表连接即可。

【代码】

1 SELECT title, description FROM film
2 WHERE film_id IN (SELECT film_id FROM film_category WHERE category_id IN
3 (SELECT category_id FROM category WHERE name = 'Action'))

31、获取select * from employees对应的执行计划

【题解】

explain模拟优化器执行SQL语句,在5.6以及以后的版本中,除过select,其他比如insert,update和delete均可以使用explain查看执行计划,从而知道mysql是如何处理sql语句,分析查询语句或者表结构的性能瓶颈。

【代码】

1 EXPLAIN SELECT * FROM employees

32、将employees表的所有员工的last_name和first_name拼接起来作为Name

【题解】

MySQL、SQL Server、Oracle等数据库支持CONCAT方法,
而本题所用的SQLite数据库只支持用连接符号"||"来连接字符串

【代码】

mysql写法:

1 SELECT CONCAT(last_name, " ", first_name) AS Name FROM employees

SQLite写法:

1 SELECT last_name ||" "|| first_name AS Name FROM employees

33、创建一个actor表,包含如下列信息

【题解】

获取系统默认时间是datetime('now','localtime')

【代码】

1 CREATE TABLE actor
2 (
3 actor_id smallint(5) NOT NULL PRIMARY KEY,
4 first_name varchar(45) NOT NULL,
5 last_name varchar(45) NOT NULL,
6 last_update timestamp NOT NULL DEFAULT (datetime('now','localtime'))
7 )

34、批量插入数据

【题解】

只需要知道INSERT INTO 表名 VALUES的用法就可以啦

【代码】

1 INSERT INTO actor VALUES (1, 'PENELOPE', 'GUINESS', '2006-02-15 12:34:33') ,
2 (2, 'NICK', 'WAHLBERG', '2006-02-15 12:34:33')

35、批量插入数据,不使用replace操作

【题解】

需要知道INSERT OR IGNORE INTO 表名 VALUES...

即如果数据存在就忽略不插入

【代码】

SQLite写法:

1 INSERT OR IGNORE INTO actor VALUES
2 (3, 'ED', 'CHASE', '2006-02-15 12:34:33')

Mysql写法:

1 INSERT IGNORE INTO actor VALUES
2 (3, 'ED', 'CHASE', '2006-02-15 12:34:33')

36、创建一个actor_name表

【题解】

把查询到的内容建表!get√

【代码】

SQLite写法:

1 CREATE TABLE actor_name AS
2 SELECT first_name, last_name FROM actor

MySQL写法:

1 CREATE TABLE actor_name
2 SELECT first_name, last_name FROM actor

37、对first_name创建唯一索引uniq_idx_firstname

【题解】

添加索引的两种方式:(不知道为啥这题第二种过不了)

①修改表:ALTER TABLE 表名 ADD (UNIQUE) INDEX ON 索引名(属性名)

②创建索引:CREATE (UNIQUE) INDEX 索引名 ON 表名(属性名)

【代码】

1 CREATE UNIQUE INDEX uniq_idx_firstname ON actor(first_name);
2 CREATE INDEX idx_lastname ON actor(last_name);
3
4 //
5 ALTER TABLE actor ADD UNIQUE INDEX uniq_idx_firstname(first_name);
6 ALTER TABLE actor ADD INDEX idx_lastname(last_name);

38、针对actor表创建视图actor_name_view

【题解】

创建视图:CREATE VIEW 视图名 AS ...

【代码】

1 CREATE VIEW actor_name_view AS
2 SELECT first_name AS first_name_v, last_name AS last_name_v
3 FROM actor

39、针对上面的salaries表emp_no字段创建索引idx_emp_no

【题解】

SQLite中,使用INDEXED语句进行强制索引查询:

SELECT * FROM salaries INDEXED BY idx_emp_no WHERE emp_no = 10005

MySQL中,使用 FORCE INDEX 语句进行强制索引查询:

SELECT * FROM salaries FORCE INDEX idx_emp_no WHERE emp_no = 10005

【代码】

1 SELECT * FROM salaries
2 INDEXED BY idx_emp_no WHERE emp_no = '10005'

40、在last_update后面新增加一列名字为create_date

【题解】

修改表结构:ARTER TABLE 表名

添加列:ADD COLUMN 列名 ...

删除列:DROP COLUMN 列名

修改列:CHANGE COLUMN 列名 新列名...

【代码】

1 ALTER TABLE actor
2 ADD COLUMN create_date datetime NOT NULL DEFAULT '0000-00-00 00:00:00'

【牛客网】数据库SQL实战(题解)的更多相关文章

  1. 牛客网数据库SQL实战解析(51-61题)

    牛客网SQL刷题地址: https://www.nowcoder.com/ta/sql?page=0 牛客网数据库SQL实战解析(01-10题): https://blog.csdn.net/u010 ...

  2. 牛客网数据库SQL实战解析(31-40题)

    牛客网SQL刷题地址: https://www.nowcoder.com/ta/sql?page=0 牛客网数据库SQL实战解析(01-10题): https://blog.csdn.net/u010 ...

  3. 牛客网数据库SQL实战解析(21-30题)

    牛客网SQL刷题地址: https://www.nowcoder.com/ta/sql?page=0 牛客网数据库SQL实战解析(01-10题): https://blog.csdn.net/u010 ...

  4. 牛客网数据库SQL实战解析(11-20题)

    牛客网SQL刷题地址: https://www.nowcoder.com/ta/sql?page=0 牛客网数据库SQL实战解析(01-10题): https://blog.csdn.net/u010 ...

  5. 牛客网数据库SQL实战解析(1-10题)

    牛客网SQL刷题地址: https://www.nowcoder.com/ta/sql?page=0 牛客网数据库SQL实战解析(01-10题): https://blog.csdn.net/u010 ...

  6. 牛客网数据库SQL实战解析(41-50题)

    牛客网SQL刷题地址: https://www.nowcoder.com/ta/sql?page=0 牛客网数据库SQL实战解析(01-10题): https://blog.csdn.net/u010 ...

  7. 牛客网数据库SQL实战(此处只有答案,没有表内容)

    1.查找最晚入职员工的所有信息   select * from employees order by hire_date desc limit 1; --limit n表示输出前n条数据,limit ...

  8. 牛客网数据库SQL实战(21-25)

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

  9. 牛客网数据库SQL实战(16-20)

    16.统计出当前各个title类型对应的员工当前薪水对应的平均工资.结果给出title以及平均工资avg.CREATE TABLE `salaries` (`emp_no` int(11) NOT N ...

  10. 牛客网数据库SQL实战(11-15)

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

随机推荐

  1. mitmproxy 代理工具介绍:rewrite和map local实现

    在接口测试中,会用到抓包工具或者代理工具,常用代理工具包括charles. burpsuite. fiddler.mitmproxy等,ssh -D参数 可实现socks5代理.网络嗅探工具可以使用t ...

  2. μC/OS-III---I笔记10---内存管理

    内存管理: 平时经常用到一些windows内存管理的软件,有一些内存管理的软件进行内存碎片的整理,在频繁分配和释放内存的地方会造成大量的内存碎片.内存碎片是如何形成的呢?书中是这样写的:在不断的分配和 ...

  3. javascript nested object merge

    javascript nested object merge deep copy Object reference type function namespace(oNamespace, sPacka ...

  4. Flutter Search Component

    Flutter Search Component flutter 搜索组件 xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

  5. Linux & bash & tcpdump

    Linux & bash & tcpdump Linux & tcpdump https://www.tecmint.com/12-tcpdump-commands-a-net ...

  6. moment.js 时间格式转换

    moment.js 时间格式转换 moment.js 时间转化 bug 格式错误 bug 02:00 => 14:00 format HH 与 hh HH === 24 小时制 hh === 1 ...

  7. 手写一个webpack,看看AST怎么用

    本文开始我会围绕webpack和babel写一系列的工程化文章,这两个工具我虽然天天用,但是对他们的原理理解的其实不是很深入,写这些文章的过程其实也是我深入学习的过程.由于webpack和babel的 ...

  8. 06_MySQL数据类型

    MySQL数据类型

  9. Spark在处理数据的时候,会将数据都加载到内存再做处理吗?

    对于Spark的初学者,往往会有一个疑问:Spark(如SparkRDD.SparkSQL)在处理数据的时候,会将数据都加载到内存再做处理吗? 很显然,答案是否定的! 对该问题产生疑问的根源还是对Sp ...

  10. Elasticsearch---DSL搜索实践

    Domain Specific Language 特定领域语言,基于JSON格式的数据查询,查询更灵活,有利于复杂查询 一.普通url路径参数搜索 数据准备 1.建立名字为 shop 的索引 2.手动 ...