【题解】
hire_date可能存在重复值,所以需要找到hire_date的最大值,然后再筛选,才能hire_date最晚的记录都筛选出来。
【代码】
1 SELECT * FROM employees 2 WHERE hire_date = (SELECT MAX(hire_date) FROM employees)
【题解】
还是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)
【题解】
这题好坑哦,因为题目中说的是“薪水详情以及其对应部门编号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
【题解】
这里需要注意一下,因为是给出每个员工入职时的薪资,所以还需要将加上这个条件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
【题解】
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
【题解】
类似第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'
【题解】
使用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)
【题解】
题意中明确说明如果是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
【题解】
可以通过两步来理解。
第一步:通过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)
【题解】
第一步:根据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
【题解】
这题比较简单,直接按题意做就可以啦。
【代码】
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、