MySQL学习-函数(十四)

107 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情

前言

上篇我们又学习了一部分MySQL中的函数。有兴趣的小伙伴可以阅读(# MySQL学习-函数(十三))。
下面继续学习MySQL中的函数。

COUNT效率

上一节罗列了COUNT函数统计表中记录数量的三种方式:

  1. COUNT(*)
  2. COUNT(1)
  3. 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_idAVG(salary)
16800.00
23200.00

GROUP BY可以将结果分组,这里按照单个列部门进行分组。

示例二

查询各个部门,工作岗位的平均工资。

方式一

SELECT department_id, job_id, AVG(salary)
FROM employees
GROUP BY department_id, job_id;
department_idjob_idAVG(salary)
1AD_PRES6800.00
2IT_PROG3200.00
2ST_MAN3200.00

以下这种方式也可以得出相同的结果:

方式二

SELECT job_id, department_id, AVG(salary)
FROM employees
GROUP BY job_id, department_id;
job_iddepartment_idAVG(salary)
AD_PRES16800.00
IT_PROG23200.00
ST_MAN23200.00

方式三

SELECT department_id, job_id, AVG(salary)
FROM employees
GROUP BY department_id;
department_idjob_idAVG(salary)
1AD_PRES6800.00
2IT_PROG3200.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_idAVG(salary)
16800.00
23200.00
NULL5000.00

可以从结果中看出,使用WITH ROLLUP后,结果会多出一行。多出一行的结果是全部数据的平均值。担忧一种情况不能使用WITH ROLLUP,请看以下示例:
查询各个部门的平均工资,按照平均工资升序排列。

SELECT department_id, AVG(salary) avg_sal
FROM employees
GROUP BY department_id
ORDER BY avg_sal ASC;
department_idavg_sal
23200.00
16800.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是互相排斥的。

今天先学习到这里,明天继续。