持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情
前言
上篇我们又学习了一部分MySQL中的函数。有兴趣的小伙伴可以阅读(# MySQL学习-函数(十三))。
下面继续学习MySQL中的函数。
COUNT效率
上一节罗列了COUNT函数统计表中记录数量的三种方式:
- COUNT(*)
- COUNT(1)
- COUNT(具体字段) 非空
上面三种方式哪种效率更高呢?
这和MySQL中的存储引擎有关。
- 如果使用的是MyISAM存储引擎,则三者效率相同,都是O(1)。
- 如果使用的是InnoDB存储引擎,则三者效率:COUNT(*) = COUNT(1) > COUNT(具体字段)
这里我们先记住结论,等学到存储引擎以及SQL优化时,再来说明原因。
GROUP BY
示例一
查询各个部门的平均工资,并按部门分组。
SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id;
| department_id | AVG(salary) |
|---|---|
| 1 | 6800.00 |
| 2 | 3200.00 |
GROUP BY可以将结果分组,这里按照单个列部门进行分组。
示例二
查询各个部门,工作岗位的平均工资。
方式一
SELECT department_id, job_id, AVG(salary)
FROM employees
GROUP BY department_id, job_id;
| department_id | job_id | AVG(salary) |
|---|---|---|
| 1 | AD_PRES | 6800.00 |
| 2 | IT_PROG | 3200.00 |
| 2 | ST_MAN | 3200.00 |
以下这种方式也可以得出相同的结果:
方式二
SELECT job_id, department_id, AVG(salary)
FROM employees
GROUP BY job_id, department_id;
| job_id | department_id | AVG(salary) |
|---|---|---|
| AD_PRES | 1 | 6800.00 |
| IT_PROG | 2 | 3200.00 |
| ST_MAN | 2 | 3200.00 |
方式三
SELECT department_id, job_id, AVG(salary)
FROM employees
GROUP BY department_id;
| department_id | job_id | AVG(salary) |
|---|---|---|
| 1 | AD_PRES | 6800.00 |
| 2 | IT_PROG | 3200.00 |
可以看到方式3查出的结果是错误的,没有把所有的job_id罗列出来。
结论1: SELECT中出现的非组函数的字段必须声明在GROUP BY中。
反之,GROUP BY中声明的字段可以不出现在SELECT中。
结论2: GROUP BY声明在FROM后面、WHERE后面,ORDER BY的前面、LIMIT的前面。
结论3: MySQL中GROUP BY中使用WITH ROLLUP。
GROUP BY中使用WITH ROLLUP
SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id WITH ROLLUP;
| department_id | AVG(salary) |
|---|---|
| 1 | 6800.00 |
| 2 | 3200.00 |
| NULL | 5000.00 |
可以从结果中看出,使用WITH ROLLUP后,结果会多出一行。多出一行的结果是全部数据的平均值。担忧一种情况不能使用WITH ROLLUP,请看以下示例:
查询各个部门的平均工资,按照平均工资升序排列。
SELECT department_id, AVG(salary) avg_sal
FROM employees
GROUP BY department_id
ORDER BY avg_sal ASC;
| department_id | avg_sal |
|---|---|
| 2 | 3200.00 |
| 1 | 6800.00 |
上面这种写法是正确的,但是如果加上WITH ROLLUP的话,下面示例:
SELECT department_id, AVG(salary) avg_sal
FROM employees
GROUP BY department_id WITH ROLLUP
ORDER BY avg_sal ASC;
运行示例发现会报错。从而得出以下结论:
当使用WITH ROLLUP时,不能同时使用ORDER BY子句进行结果排序,即WITH ROLLUP和ORDER BY是互相排斥的。
今天先学习到这里,明天继续。