Mysql关键字之Group By(一)
原文地址,优先更新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(一)的更多相关文章
- Mysql关键字之Group By(二)
原文地址,优先更新https://hhe0.github.io 我们在上一节简单介绍了Mysql中group by关键字的用法,没有看过的同学点击这里了解一下; 文中提到的courses表和相关记录可 ...
- MySQL关键字
MySQL关键字 ADD ALL ALTER ANALYZE AND AS ASC ASENSITIVE BEFORE BETWEEN BIGINT BINARY BLOB BOTH BY CALL ...
- mysql 关键字于数据库字段于关键字冲突的问题
如果数据库存储字段 为MySQL关键字,那么在查询或者其他操作时会出错.那么我们应该怎么办, 可能有些人会说,换个字段不就好了啊.当然这样也是可以的,完全没问题. 然而,如果是在无法对数据库进行修改和 ...
- MySQL字段命名不能使用的MySQL关键字
#今天遇到一个问题,把某一字段重新命名为condition时报错,于是联想到可能是MySQL的关键字,用``引起来后,问题解决. #在MySQL数据库中,Table字段不能使用MySQL关键字: #[ ...
- mysql distinct跟group by性能
mysql distinct和group by性能 1,测试前的准备 //准备一张测试表 mysql> CREATE TABLE `test_test` ( -> `id` int ...
- Oracle和MySQL分组查询GROUP BY
Oracle和MySQL分组查询GROUP BY 真题1.Oracle和MySQL中的分组(GROUP BY)有什么区别? 答案:Oracle对于GROUP BY是严格的,所有要SELECT出来的字段 ...
- MySQL 中的反引号(`):是为了区分 MySql 关键字与普通字符而引入的符号;一般,表名与字段名都使用反引号。
MySQL 中的反引号(`):是为了区分 MySql 关键字与普通字符而引入的符号:一般,表名与字段名都使用反引号.
- 在mysql中使用group by和order by取每个分组中日期最大一行数据
转载自:https://blog.csdn.net/shiyong1949/article/details/78482737 在mysql中使用group by进行分组后取某一列的最大值,我们可以直接 ...
- [MySQL 5.6] MySQL 5.6 group commit 性能测试及内部实现流程
[MySQL 5.6] MySQL 5.6 group commit 性能测试及内部实现流程 http://mysqllover.com/?p=581 尽管Mariadb以及Facebook在long ...
随机推荐
- Netlink: 内核与用户空间传输数据的socket协议
https://en.wikipedia.org/wiki/Netlink https://stackoverflow.com/questions/12899055/how-kernel-notify ...
- Java-最常用的Java日志框架整理
Java-最常用的Java日志框架整理 前言 Java程序员,我们开发了很多Java应用程序,包括桌面应用.WEB应用以及移动应用.然而日志系统是一个成熟Java应用所必不可少的,在开发和调试阶段,日 ...
- 自已编译openweb docker image笔记
1.基于https://github.com/jketterl/openwebrx git clone https://github.com/jketterl/openwebrx.git 2.首先创建 ...
- kubernetes里面的GC--转发
什么是GC GC 是 Garbage Collector 的简称.从功能层面上来说,它和编程语言当中的「GC」 基本上是一样的.它清理 Kubernetes 中「符合特定条件」的 Resource O ...
- linux系统中如何查看最后一封mail
1. mail命令查看邮件列表 2.file 命令查看一共多少封邮件 3.直接键入278 查看最后一封邮件内容 4. 输入q 从邮件阅读模式退出
- 下载恶意pcap包的网站汇总
说几个我经常用的,免费的:1. Malware Traffic Analysis: http://www.malware-traffic-analysis.net/2018/index.htm ...
- re正则match、search、findall、finditer函数方法使用
match 匹配string 开头,成功返回Match object, 失败返回None,只匹配一个. search 在string中进行搜索,成功返回Match object, 失败返回None, ...
- Centos7安装使用Mysql(mariadb)
安装 shell> yum install mariadb-server -y 配置 # 修改文件 /etc/my.cnf [mysqld]datadir=/mydata/data/mysqlc ...
- python - django 控制台输出 sql 语句
只需要在 settings.py 文件中加入以下配置即可. LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers ...
- BZOJ 5338: [TJOI2018]xor 可持久化trie+dfs序
强行把序列问题放树上,好无聊啊~ code: #include <bits/stdc++.h> #define N 200005 #define setIO(s) freopen(s&qu ...