「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战」
描述
有一个部门表departments简况如下:
有一个,部门员工关系表dept_emp简况如下:
有一个职称表titles简况如下:
汇总各个部门当前员工的title类型的分配数目,即结果给出部门编号dept_no、dept_name、其部门下所有的员工的title以及该类型title对应的数目count,结果按照dept_no升序排序,dept_no一样的再按title升序排序
示例1
drop table if exists `departments` ;
drop table if exists `dept_emp` ;
drop table if exists titles ;
CREATE TABLE `departments` (
`dept_no` char(4) NOT NULL,
`dept_name` varchar(40) NOT NULL,
PRIMARY KEY (`dept_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 titles (
`emp_no` int(11) NOT NULL,
`title` varchar(50) NOT NULL,
`from_date` date NOT NULL,
`to_date` date DEFAULT NULL);
INSERT INTO departments VALUES('d001','Marketing');
INSERT INTO departments VALUES('d002','Finance');
INSERT INTO dept_emp VALUES(10001,'d001','1986-06-26','9999-01-01');
INSERT INTO dept_emp VALUES(10002,'d001','1996-08-03','9999-01-01');
INSERT INTO dept_emp VALUES(10003,'d002','1995-12-03','9999-01-01');
INSERT INTO titles VALUES(10001,'Senior Engineer','1986-06-26','9999-01-01');
INSERT INTO titles VALUES(10002,'Staff','1996-08-03','9999-01-01');
INSERT INTO titles VALUES(10003,'Senior Engineer','1995-12-03','9999-01-01');
结果:
d001|Marketing|Senior Engineer|1
d001|Marketing|Staff|1
d002|Finance|Senior Engineer|1
方法一
先将题目要求的列都查询出来,放到一个结果集中;再将这个结果集作为表查询题目所要求的答案;
SELECT dept_no, dept_name, title, COUNT(*)
FROM
(
SELECT A.*, B.title
FROM
(SELECT a.emp_no, a.dept_no, b.dept_name FROM dept_emp a, departments b WHERE a.dept_no=b.dept_no) A,
titles B
WHERE A.emp_no=B.emp_no
) C
GROUP BY dept_no, title
ORDER BY dept_no, title
运行效果
按照惯例,我们打开optimizer_trace来看看具体发生了什么
在准备阶段,mysql内部将语句优化成了如下:
SELECT a.dept_no, b.dept_name, B.title, COUNT(0)
FROM dept_emp a, departments b, titles B
WHERE a.emp_no=B.emp_no AND a.dept_no=b.dept_no
GROUP BY a.dept_no, B.title
ORDER BY a.dept_no, B.title;
看起来确实比我自己写的简洁了许多;
由于三表连接,方式有许多种,这里只说明最后的连接顺序为b->B->a,b驱动B驱动a;此种方法开销最低,开销为10.8;