思路:这题可以有三种解法。 第一二种类似,区别在于第一种方法是使用left join,第二种使用 inner join,其实区别并不大,酌情使用即可

-- 方法一:

select dp.dept_no, dp.dept_name, count(s.salary) as sum
from salaries s left join dept_emp d
on s.emp_no = d.emp_no
left join departments dp
on d.dept_no = dp.dept_no
group by dp.dept_no
order by dp.dept_no

-- 方法二:

select d.dept_no, d.dept_name, count(s.salary) as sum
from departments d join dept_emp de 
on d.dept_no = de.dept_no
join salaries s 
on de.emp_no = s.emp_no
group by d.dept_no
order by d.dept_no

大家可能会有疑问。为什么明明这里group by是对 dept_no 进行分组,但是select 子句后可以使用 dp.dept_name。 这是因为

当group by 后面跟上主键或者不为空唯一索引时,查询是有效的,因为此时的每一笔数据都具有唯一性。

我们可以从departments表中看出,每一个 dept_no 都是对应一个 dept_name 的,所以在select 子句后可以使用。但是在其他不是一一对应关系的情况下,这种查询是错误的

方法三:传统的按步骤来进行计算

思路:

  1. 查询每个员工在salaries表中的记录数:
select emp_no,count(emp_no) as counts from salaries group by emp_no
  1. 然后与dept_emp表连接,生成一个包含dept_no,emp_no,counts字段的临时表:
select de.dept_no,de.emp_no,en.counts 
from dept_emp de 
inner join (select emp_no,count(emp_no) as counts from salaries group by emp_no) as en
on de.emp_no = en.emp_no
  1. 最后将第二步生成的临时表再和departments进行连接,以dept_no分组,计算对于部门的所有员工的counts的总和,生成字段sum。最后进行order by排序
select d.dept_no, d.dept_name, sum(ds.counts)
from departments d join (
select de.dept_no, de.emp_no, en.counts
from 
dept_emp de join (select emp_no, count(emp_no) as counts from salaries group by emp_no) as en
on de.emp_no = en.emp_no
) as ds
on d.dept_no = ds.dept_no
group by d.dept_no
order by d.dept_no