原文地址,优先更新https://hhe0.github.io

group by 是一个我们在日常工作学习过程中经常遇到的一个Mysql关键字。现总结其用法如下,内容会不断补充,出现错误欢迎批评指正。

我们先准备一张表和一些记录

我们首先创建学生的成绩表courses:

CREATE TABLE `courses` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增id',
`student` VARCHAR(255) DEFAULT NULL COMMENT '学生',
`class` VARCHAR(255) DEFAULT NULL COMMENT '课程',
`score` INT(255) DEFAULT NULL COMMENT '分数',
PRIMARY KEY (`id`),
UNIQUE KEY `course` (`student`, `class`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

该表记录了学生某节课的考试分数。

courses表中插入记录:

INSERT INTO `courses`(`student`, `class`, `score`) VALUES('A', 'Math', 90);
INSERT INTO `courses`(`student`, `class`, `score`) VALUES('A', 'Chinese', 80);
INSERT INTO `courses`(`student`, `class`, `score`) VALUES('A', 'English', 70);
INSERT INTO `courses`(`student`, `class`, `score`) VALUES('A', 'History', 80); INSERT INTO `courses`(`student`, `class`, `score`) VALUES('B', 'Math', 73);
INSERT INTO `courses`(`student`, `class`, `score`) VALUES('B', 'Chinese', 60);
INSERT INTO `courses`(`student`, `class`, `score`) VALUES('B', 'English', 70);
INSERT INTO `courses`(`student`, `class`, `score`) VALUES('B', 'History', 90); INSERT INTO `courses`(`student`, `class`, `score`) VALUES('C', 'Math', 70);
INSERT INTO `courses`(`student`, `class`, `score`) VALUES('C', 'Chinese', 50);
INSERT INTO `courses`(`student`, `class`, `score`) VALUES('C', 'English', 20);
INSERT INTO `courses`(`student`, `class`, `score`) VALUES('C', 'History', 10); INSERT INTO `courses`(`student`, `class`, `score`) VALUES('D', 'Math', 53);
INSERT INTO `courses`(`student`, `class`, `score`) VALUES('D', 'Chinese', 32);
INSERT INTO `courses`(`student`, `class`, `score`) VALUES('D', 'English', 99);
INSERT INTO `courses`(`student`, `class`, `score`) VALUES('D', 'History', 100);

Group By有什么用

我们使用几个简单的例子看一下group by的作用:

SELECT * FROM `courses` GROUP BY `class`;

执行的结果是:

![企业微信截图_20180820143057.png-7.3kB][1]
类似地,我们按照`score`对记录进行分组:
```sql
SELECT * FROM `courses` GROUP BY `score`;
```
执行的结果是:
![ScreenClip.png-13.8kB][2]
我们甚至可以对多个字段进行`group by`:
```sql
SELECT * FROM `courses` GROUP BY `class`,`student`;
```
执行的结果是:
![ScreenClip.png-14.3kB][3]
最后,我们交换字段顺序对记录进行分组:
```sql
SELECT * FROM `courses` GROUP BY `student`,`class`;
```
执行的结果是:
![ScreenClip.png-17.2kB][4]
这样的结果可能会使人困惑,我们以第一个sql为例,解释下sql执行的过程:
![未命名文件.png-62.2kB][5]
该`sql`首先会按照`class`进行分组得到四张中间表,然后输出的时候将每一个分组的第一个记录组合在一起形成了最终的结果。我们还可以发现,最终的记录是按照`class`进行排序的。这样的顺序并不可靠,具体形成的原因恐怕需要在`Mysql`的底层原理中找到答案。
## Group By还能怎么用
### 与order by结合在一起使用
> 我们需要学生的成绩表,且每个学生每科的成绩按照由大到小的顺序排列

我们可以很自然的写出下面的sql:

SELECT * FROM `courses` GROUP BY `student`,`class` ORDER BY `score` DESC;

然而,执行的结果貌似并不是我们想要的:

![ScreenClip.png-16.6kB][6]
通过观察,我们可以发现,事实上,这个`sql`是将所有的记录按照`score`由大到小的顺序排列了,为什么会出现这样的结果呢?
事实上,这个取决于整个`sql`的执行顺序,真正的执行顺序是 `from` ... `where` ... `group by` ... `order by` ... `select`,`order by` 作用在整个记录,而不是每个分组上。
那么,怎么样能够得到我们期望的结果呢?这里给出我的`sql`实现:
```sql
SELECT * FROM `courses` GROUP BY `student`,`class` ORDER BY `student`,`score` DESC;
```
执行的结果是:
![ScreenClip.png-19.8kB][7]

与having结合在一起使用

我们需要得到所有功课平均分达到60分的同学和他们的均分:

SELECT `student`, AVG(`score`) AS`avg_score`
FROM `courses`
GROUP BY `student`
HAVING AVG(`score`) >= 60
ORDER BY `avg_score` DESC;

执行的结果为:

![ScreenClip (8).png-3.8kB][8]
这里需要注意一个问题:`where` 与 `having`的区别。`where`作用于所有的记录,而`having`则作用于一个分组。
举例说明:
> 假设我们这里需要得到所有功课(除历史课)平均分达到60分的同学和他们的均分:

SELECT `student`, AVG(`score`) AS `avg_score`
FROM `courses`
WHERE `class` <> 'History'
GROUP BY `student`
HAVING AVG(`score`) >= 60
ORDER BY `avg_score` DESC;

执行的结果如下:

![ScreenClip.png-3.1kB][9]
### Group By与Limit
> 我们需要列出均分最高的三门课:

SELECT `class`, AVG(`score`) AS `avg_score`
FROM `courses`
GROUP By `class`
ORDER BY `avg_score` DESC
LIMIT 3;

执行的结果如下:

![ScreenClip.png-3.8kB][10]
我们需要理解的是:`group by`分组的依据,以及`where`过滤条件作用的粒度
如果你觉得你已经理解了`group by`关键字的用法,欢迎移步至Mysql关键字之Group By(二),有点小练习在等着你。。。

Mysql关键字之Group By(一)的更多相关文章

  1. Mysql关键字之Group By(二)

    原文地址,优先更新https://hhe0.github.io 我们在上一节简单介绍了Mysql中group by关键字的用法,没有看过的同学点击这里了解一下; 文中提到的courses表和相关记录可 ...

  2. MySQL关键字

    MySQL关键字 ADD ALL ALTER ANALYZE AND AS ASC ASENSITIVE BEFORE BETWEEN BIGINT BINARY BLOB BOTH BY CALL ...

  3. mysql 关键字于数据库字段于关键字冲突的问题

    如果数据库存储字段 为MySQL关键字,那么在查询或者其他操作时会出错.那么我们应该怎么办, 可能有些人会说,换个字段不就好了啊.当然这样也是可以的,完全没问题. 然而,如果是在无法对数据库进行修改和 ...

  4. MySQL字段命名不能使用的MySQL关键字

    #今天遇到一个问题,把某一字段重新命名为condition时报错,于是联想到可能是MySQL的关键字,用``引起来后,问题解决. #在MySQL数据库中,Table字段不能使用MySQL关键字: #[ ...

  5. mysql distinct跟group by性能

    mysql distinct和group by性能   1,测试前的准备 //准备一张测试表 mysql> CREATE TABLE `test_test` ( ->   `id` int ...

  6. Oracle和MySQL分组查询GROUP BY

    Oracle和MySQL分组查询GROUP BY 真题1.Oracle和MySQL中的分组(GROUP BY)有什么区别? 答案:Oracle对于GROUP BY是严格的,所有要SELECT出来的字段 ...

  7. MySQL 中的反引号(`):是为了区分 MySql 关键字与普通字符而引入的符号;一般,表名与字段名都使用反引号。

    MySQL 中的反引号(`):是为了区分 MySql 关键字与普通字符而引入的符号:一般,表名与字段名都使用反引号.

  8. 在mysql中使用group by和order by取每个分组中日期最大一行数据

    转载自:https://blog.csdn.net/shiyong1949/article/details/78482737 在mysql中使用group by进行分组后取某一列的最大值,我们可以直接 ...

  9. [MySQL 5.6] MySQL 5.6 group commit 性能测试及内部实现流程

    [MySQL 5.6] MySQL 5.6 group commit 性能测试及内部实现流程 http://mysqllover.com/?p=581 尽管Mariadb以及Facebook在long ...

随机推荐

  1. linux设备驱动程序--串行通信驱动框架分析

    linux 串行通信接口驱动框架 在学习linux内核驱动时,不论是看linux相关的书籍,又或者是直接看linux的源码,总是能在linux中看到各种各样的框架,linux内核极其庞杂,linux各 ...

  2. Pthon魔术方法(Magic Methods)-反射

    Pthon魔术方法(Magic Methods)-反射 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.反射概述 运行时,区别于编译时,指的时程序被加载到内存中执行的时候. 反射 ...

  3. jquery 插入节点

    往某个元素内部的结尾添加 append() appendTo() append() <body> <button id="bt1">点击通过jQuery的a ...

  4. Codeforces E. Alyona and a tree(二分树上差分)

    题目描述: Alyona and a tree time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  5. 逆向破解之160个CrackMe —— 007

    CrackMe —— 007 160 CrackMe 是比较适合新手学习逆向破解的CrackMe的一个集合一共160个待逆向破解的程序 CrackMe:它们都是一些公开给别人尝试破解的小程序,制作 c ...

  6. monkey内存泄露

    monkey内存泄露 1.内存泄露发现方法 执行monkey测试时有时会有内存泄露情况,可以进行排查 a.手机弹出out of  memory对话框--基本确定有内存泄露 b.手机没有提示但是实际有内 ...

  7. MySQL备份的三中方式

    一.备份的目的 做灾难恢复:对损坏的数据进行恢复和还原需求改变:因需求改变而需要把数据还原到改变以前测试:测试新功能是否可用 二.备份需要考虑的问题 可以容忍丢失多长时间的数据:恢复数据要在多长时间内 ...

  8. mysql udf提权

    参考文章:https://blog.csdn.net/q1352483315/article/details/98483668

  9. Statistical Methods for Machine Learning

    机器学习中的统计学方法. 从机器学习的核心视角来看,优化(optimization)和统计(statistics)是其最最重要的两项支撑技术.统计的方法可以用来机器学习,比如:聚类.贝叶斯等等,当然机 ...

  10. Selenium ChromeDriver与Chrome版本映射表(更新到v77)

    ChromeDriver版本 支持的Chrome版本 v77.0.3865.40 v77 v76.0.3809.126 v76 v75.0.3770.140 v75 v74 v74 v73 v73 v ...