题目:统计各个部门的工资记录数,给出部门编码dept_no,部门名称dept_name以及次数sum
方法1:嵌套查询,查出一个dept_no,就进行子查询的到对应COUNT()
SELECT dept_no, dept_name, (SELECT COUNT()
FROM dept_emp AS de
INNER JOIN salaries AS s
ON de.emp_no=s.emp_no
WHERE de.dept_no=d.dept_no) AS sum
FROM departments AS d;
注意:对于这种情形的子查询,一个部门进去,必须只返回一个值,而且只能查询一个列,可以参考26题的错误示范做对比
方法2:先进行两次内连接,再通过GROUP BY查询
SELECT de.dept_no, de.dept_name, COUNT(*) AS sum
FROM (SELECT *
FROM departments
INNER JOIN dept_emp
ON departments.dept_no=dept_emp.dept_no) AS de
INNER JOIN salaries AS s
ON de.emp_no=s.emp_no
GROUP BY de.dept_no;
注意:这里GROUP BY聚合dept_no,而dept_name看上去不是聚合列(因此似乎不能放进SELECT语句内),但是事实上,由于dept_no是主键,所以一个dept_no只会对应一个dept_name,所以可以认为dept_name是可聚合的,所以可以放进去。特别要注意的是,如果dept_no不是主键,而是联合主键之一或者别的情况,总之dept_no不能唯一确定dept_name,那么即使在表中看上去dept_no和dept_name是一一对应的,也不能将dept_name放进SELECT中,强行放进去,在mysql中也会报错(当然在题库中不会报错)。
补充:内层的内连接,可以省略SELECT (因为内连接自己会生成临时表):
SELECT de.dept_no, de.dept_name, COUNT() AS sum
FROM (departments
INNER JOIN dept_emp
ON departments.dept_no=dept_emp.dept_no) AS de
INNER JOIN salaries AS s
ON de.emp_no=s.emp_no
GROUP BY de.dept_no;
补充:还可以进一步省略,直接进行连续内连接:
SELECT d.dept_no, d.dept_name, COUNT(*) AS sum
FROM
(departments AS d
INNER JOIN dept_emp AS de
ON d.dept_no=de.dept_no
INNER JOIN salaries AS s
ON de.emp_no=s.emp_no)
GROUP BY de.dept_no;
注意:连续内连接中一定不要出现WHERE(21题的经验)
方法3:直接三表联查,用WHERE过滤
SELECT d.dept_no, d.dept_name, COUNT(*) AS sum
FROM departments AS d, dept_emp AS de, salaries AS s
WHERE d.dept_no=de.dept_no
AND de.emp_no=s.emp_no
GROUP BY d.dept_no;
备注:三表联查在代码上比进行两次内连接简洁