Mysql从入门到入魔——5. 聚集、分组、子查询

  • 1. 数据聚集
    • 1.1 聚集函数
      • 1.1.1 AVG()函数
      • 1.1.2 COUNT()函数
      • 1.1.3 MAX()函数
      • 1.1.4 MIN()函数
      • 1.1.5 SUM()函数
    • 1.2 组合聚集函数
  • 2. 数据分组
    • 2.1 数据分组
    • 2.2 过滤分组
  • 3. 子查询
    • 3.1 子查询的划分
    • 3.2 WHERE 或 HAVING后的子查询
      • 3.2.1 单行子查询
      • 3.2.2 多行子查询
    • 3.3 SELECT后的子查询
    • 3.4 FROM后的子查询
    • 3.5 EXISTS后的子查询(相关子查询)

❤ 系列内容 ❤

Mysql从入门到入魔——1. 数据准备(起航篇)
Mysql从入门到入魔——2. 操纵数据库和表
Mysql从入门到入魔——3. 查询、排序、WHERE过滤
Mysql从入门到入魔——4. 通配符、计算字段、函数
Mysql从入门到入魔——5. 聚集、分组、子查询
Mysql从入门到入魔——6. 表联结、组合查询
Mysql从入门到入魔——7. 插入、更新和删除
Mysql从入门到入魔——8. 视图、存储过程、事务处理
Mysql从入门到入魔——9. 游标、高级SQL特性
Mysql从入门到入魔——10. 知识点速记(完结)


本篇主要内容

六种聚集函数的使用,ORDER BY 数据分组,子查询( 相关子查询 与 不相关子查询 )。内容稍稍有些多,需要静下心来慢慢看,如果条件允许可以动手实践一下(数据库文件在系列首页)。话不多说,进入正题!



1. 数据聚集

1.1 聚集函数

先来看一下,我们常用的聚集函数和它的说明。

函数 说明
AVG() 返回某列的平均值
COUNT() 返回某列的行数
MAX() 返回某列的最大值
MIN() 返回某列的最小值
SUM() 返回某列值之和

1.1.1 AVG()函数

查询供应商 id'DLL01' 的所有商品的平均价格。

mysql> SELECT AVG(prod_price) AS avg_price-> FROM Products-> WHERE vend_id = 'DLL01';
+-----------+
| avg_price |
+-----------+
|  3.865000 |
+-----------+

1.1.2 COUNT()函数

两种使用方式:

  • COUNT(*) 对表中行的数目进行计数,包括 空值

查询 Customers 表中的顾客数量。

mysql> SELECT COUNT(*) AS num_cust-> FROM Customers;
+----------+
| num_cust |
+----------+
|        5 |
+----------+
  • COUNT(column) 对特定列中非 NULL 行进行计数。

查询 Customers 表中非空邮箱数。

mysql> SELECT COUNT(cust_email) AS num_cust-> FROM Customers;
+----------+
| num_cust |
+----------+
|        3 |
+----------+

1.1.3 MAX()函数

column 列为数值列, MAX(column) 返回 column 列中的最大值。

column 列为文本数据, MAX(column) 返回 column 列数据 排序 后的最后一行。

1.1.4 MIN()函数

column 列为数值列, MIN(column) 返回 column 列中的最小值。

column 列为文本数据, MIN(column) 返回 column 列数据 排序 后的最前面的行。

1.1.5 SUM()函数

SUM() 用来返回指定列值的和(总计)(忽略列值为 NULL 的行)。
查询 OrderItems 表中的商品总价之和。先计算出(数量 * 物品单价),再对其求和。

mysql> SELECT SUM(quantity * item_price) AS total_price-> FROM OrderItems;
+-------------+
| total_price |
+-------------+
|     5730.70 |
+-------------+

1.2 组合聚集函数

计算 Products 表中物品的数目,产品价格的最高值、最低值以及平均值。

mysql> SELECT COUNT(*) AS num_items,-> MIN(prod_price) AS price_min,-> MAX(prod_price) AS price_max,-> AVG(prod_price) AS price_avg-> FROM Products;
+-----------+-----------+-----------+-----------+
| num_items | price_min | price_max | price_avg |
+-----------+-----------+-----------+-----------+
|         9 |      3.49 |     11.99 |  6.823333 |
+-----------+-----------+-----------+-----------+

2. 数据分组

2.1 数据分组

使用分组将数据分为多个逻辑组, 对每个组进行聚集计算。使用聚集函数才能够

统计各个供应商的产品数量。

mysql> SELECT vend_id, COUNT(*) AS num_prods-> FROM Products-> GROUP BY vend_id;
+---------+-----------+
| vend_id | num_prods |
+---------+-----------+
| BRS01   |         3 |
| DLL01   |         4 |
| FNG01   |         2 |
+---------+-----------+

group by 注意事项:

  • GROUP BY 可以嵌套使用。
  • GROUP BY 子句中列出的每一列都必须是检索列或有效的表达式(但不能是聚集函数)。如果在 SELECT 中使用表达式,则必须在 GROUP BY 子句中指定相同的表达式。不能使用别名
  • 除聚集计算语句外,SELECT 语句中的每一列都必须在 GROUP BY 子句 中给出。
  • 如果分组列中包含具有 NULL 值的行,则 NULL 将作为一个分组返回。 如果列中有多行 NULL 值,它们将分为一组。
  • GROUP BY 子句必须出现在 WHERE 子句之后,ORDER BY 子句之前。

2.2 过滤分组

使用 HAVING 子句在数据分组后进行过滤。

例:查询 Products 表中有两个以上产品且其价格大于等于 4 的供应商。

mysql> SELECT vend_id, COUNT(*) AS num_prods-> FROM Products-> WHERE prod_price >= 4-> GROUP BY vend_id-> HAVING COUNT(*) >= 2;
+---------+-----------+
| vend_id | num_prods |
+---------+-----------+
| BRS01   |         3 |
| FNG01   |         2 |
+---------+-----------+

WHEREHAVING 的主要区别:

  • WHERE 是一个约束声明,HAVING 是一个过滤声明。
  • WHERE 在数据分组前进行过滤,HAVING 在数据分组后进行过滤。

SELECT 子句顺序:

子句 说明 是否必须使用
SELECT 要返回的列或表达式
FROM 从中检索数据的表 仅在从表选择数据时使用
WHERE 行级过滤
GROUP BY 分组说明 仅在按组计算聚集时使用
HAVING 组级过滤
ORDER BY 输出排序顺序

3. 子查询

3.1 子查询的划分

按照相关性来分:分为 相关子查询不相关子查询

  • 不相关子查询

  • 描述:子查询可独立执行,不依赖于父查询表的查询,称为不相关子查询。

  • 执行过程:
    (1)先执行子查询,其结果不会被显示,而是返回给外部查询来作为外部查询的查询条件;
    (2)根据子查询的结果,执行外部查询。

  • 相关子查询

  • 描述:子查询的查询条件中需要用到父查询的某一个属性列,这样的查询称为相关子查询。相关子查询是无法独立执行的,因为它必然含有对外部查询表中元组分量的引用。

  • 执行过程:
    (1)按顺序从外部查询中取出一个元组,将元组的相关分量值传递给子查询;
    (2)执行子查询,得到结果值;
    (3)外部查询根据子查询返回的结果或结果集确定取出的这一行元组是否满足条件;若外层的 where 子句返回真值,说明符合;否则不符合,则舍弃。
    (4)重复上面三步,直到外部查询表中的所有元组都被处理完毕。

按照子查询所在位置分:WHEREHAVING 后、SELECT 后、FROM 后、EXISTS 后的子查询。
下面按照位置划分来进行介绍,期间会标注示例是否为相关子查询。

3.2 WHERE 或 HAVING后的子查询

3.2.1 单行子查询

在订单表中查找最早日期的订单信息。子查询返回一行查询结果。(该示例为不相关子查询)

mysql> SELECT *-> FROM Orders-> WHERE order_date = (SELECT MIN(order_date)->                     FROM Orders);
+-----------+---------------------+------------+
| order_num | order_date          | cust_id    |
+-----------+---------------------+------------+
|     20006 | 2012-01-12 00:00:00 | 1000000003 |
+-----------+---------------------+------------+

3.2.2 多行子查询

查询订购物品 RGAN01 的所有顾客。这时子查询先从 OrderItems 表中找出包含 RGAN01 物品的订单号,再根据这些订单号在 Orders 表中找到对应的顾客 id 。(该示例为不相关子查询)

mysql> SELECT cust_id-> FROM Orders-> WHERE order_num IN (SELECT order_num->                     FROM OrderItems->                     WHERE prod_id = 'RGAN01');
+------------+
| cust_id    |
+------------+
| 1000000004 |
| 1000000005 |
+------------+
操作符 含义
IN / NOT IN 在列表中 / 不在列表中
ANY / SOME 和子查询返回的某一个值比较
ALL 同子查询结果中所有值进行比较

用法对比
ANY / SOME

  • SELECT ... FROM ... WHERE num > ANY(num1, num2)
  • 等价于
  • SELECT ... FROM ... WHERE num > num1 OR num > num2

ALL

  • SELECT ... FROM ... WHERE num > ALL(num1, num2)
  • 等价于
  • SELECT ... FROM ... WHERE num > num1 AND num > num2

注意

  • SELECT 语句中,子查询总是从内向外处理。

3.3 SELECT后的子查询

假如需要显示 Customers 表中每个顾客的订单总数。首先,从 Customers 表中检索顾客列表,然后对于检索出的每个顾客,统计其在 Orders 表中的订单数目。(该示例为相关子查询)

mysql> SELECT cust_name,->  (SELECT COUNT(*)->   FROM Orders AS ord->   WHERE ord.cust_id = cust.cust_id) AS order_count-> FROM Customers AS cust;
+---------------+-------------+
| cust_name     | order_count |
+---------------+-------------+
| Village Toys  |           2 |
| Kids Place    |           0 |
| Fun4All       |           1 |
| Fun4All       |           1 |
| The Toy Store |           1 |
+---------------+-------------+

注意:上面的例子中使用的是 Ord.cust_idcust.cust_id ,而不是直接使用 cust_id ,因为在两个表中都有 cust_id 列,在有可能混淆列名时必须使用这种语法。

3.4 FROM后的子查询

将子查询结果作为一张表,并必须要起别名。
下面的例子可能有点复杂,它还涉及到之后我们将学习的表联结,这里使用的联结方式是内联结,根据设定的条件进行等值联结。

查询目标为美国供应商名称和它的产品名称,我们一步步分析,首先先通过子查询获取供应商 Vendors 表中国家为 USA 的供应商信息,再将子查询的结果作为 USA_Vendors 表,将 Products 表与该表联结,联结条件为两表 vend_id 列相等。(该示例为不相关子查询)

mysql> SELECT vend_name, prod_name-> FROM Products, (SELECT *->                 FROM Vendors->                 WHERE vend_country = 'USA') AS USA_Vendors-> WHERE Products.vend_id = USA_Vendors.vend_id;
+-----------------+---------------------+
| vend_name       | prod_name           |
+-----------------+---------------------+
| Bears R Us      | 8 inch teddy bear   |
| Bears R Us      | 12 inch teddy bear  |
| Bears R Us      | 18 inch teddy bear  |
| Doll House Inc. | Fish bean bag toy   |
| Doll House Inc. | Bird bean bag toy   |
| Doll House Inc. | Rabbit bean bag toy |
| Doll House Inc. | Raggedy Ann         |
+-----------------+---------------------+

3.5 EXISTS后的子查询(相关子查询)

现在使用 EXISTS 来实现上面 IN 实现的查询。即查询订购物品 RGAN01 的所有顾客。

mysql> SELECT cust_id-> FROM Orders AS ord-> WHERE EXISTS (SELECT *->               FROM OrderItems AS ori->               WHERE ord.order_num = ori.order_num->                AND prod_id = 'RGAN01');
+------------+
| cust_id    |
+------------+
| 1000000004 |
| 1000000005 |
+------------+

这就是本文所有的内容了,如果感觉还不错的话。❤ 点个赞再走吧!!!❤


后续会继续分享《Mysql从入门到入魔》系列文章,如果感兴趣的话可以点个关注不迷路哦~。

Mysql从入门到入魔——5. 聚集、分组、子查询相关推荐

  1. Mysql从入门到入魔——7. 插入、更新和删除

    Mysql从入门到入魔--7. 插入.更新和删除 1. 插入数据 1.1 插入完整行 1.2 插入部分行 1.3 插入检索出的数据 1.4从一个表复制到另一个表 2.更新数据 2.1 更新单行单列 2 ...

  2. mysql 14.12_MySQL必知必会12-14 汇总 分组 子查询

    12 汇总数据-用聚集类函数 用于诸如:表中的行数.表中行组的和.列中的最大值平均值等. (python的dataframe 在输出此类结果时有优势) MySQL 五个聚集函数(其它还有:标准偏差聚集 ...

  3. Mysql入门学习(二)之子查询+关联

    关联查询(重点) 1.1 子查询 概述:一个查询的结果作为另一个查询的条件 语法:SELECT 列名 FROM 表名 Where 条件(子查询结果) 案例: 查询工资大于Bruce 的员工信息 1.先 ...

  4. Mysql时间数据分段累加求和案例之子查询与SUM窗口函数

    Mysql时间段数分段据累加求和 简介 时间段数据的分段可以根据义务逻辑来划分,累加求和在mysql8.0及以上可以通过sum结合窗口函数来实现,低版本用子查询实现. 需求 对原始数据按照时间点3点前 ...

  5. 阿里云AI训练营SQL入门到实践 Task3:视图、子查询、函数等

    视图 视图是什么 视图是一个虚拟的表,视图是依据SELECT语句来创建的,所以操作视图时会根据创建视图的SELECT语句生成一张虚拟表,然后在这张虚拟表上做SQL操作. [外链图片转存失败,源站可能有 ...

  6. 记一次mysql优化 not in, not exits, left join 子查询

    在某次业务逻辑中写到如下逻辑:查询学校级别的未拦截弹窗记录.而弹窗设备表(t_block_blacklist_device)有四种类型(1:学校级黑名单 2:设备级别黑名单 3:略 4:学校级白名单 ...

  7. 史上最简单的 MySQL 教程(三十二)「子查询(下)」

    子查询 子查询:sub query,查询是在某个查询结果之上进行的,一条select语句内部包含了另外一条select语句. 行子查询 行子查询,返回的结果可以使一行多列或者多行多列. 需求:查询学生 ...

  8. 【MySQL快速入门】牛客网:条件查询(1)基础排序

    查询后排序: 排序子句为: 1 2 ORDER BY <列名> [ASC | DESC ] [,<列名> -  例:将学生按班号的升序排序 select *from 学生表 o ...

  9. Hive 外部表的练习(多表关联查询,以及分组,子查询)

    Hive 外部表的练习 hive创建库和表操作 hive加载数据,4种发放 1.数据放在Linux创建表结构 进行加载 2.先定义表结构.将一个查询select语句结果插入到表中 3.数据先放在hdf ...

  10. mysql子查询 分组,Mysql子查询实现分组取最指定数据的版本差异

    mysql通过group by 分组子查询时,会自动保留最先搜索出来的数据.通过这个特性可以实现想要的结果,比如查询每科目考试第一名的同学成绩.查询每班最后一名到校的学生或者或者每班最先到校的学生.所 ...

最新文章

  1. [BZOJ 1150] 数据备份
  2. 博弈论进阶之Anti-SG游戏与SJ定理
  3. 第一次作业源于计科一班的王相博
  4. Python从2.6升级到2.7,使用pip安装module,报错:No Module named pip.log(转载)
  5. 代码设置环境变量QProcess类
  6. ARP协议报文格式及ARP表简述
  7. 通过IDA Pro生成asm文件
  8. RabbitVCS安装
  9. 公文流转 php,河北金力集团公文流转系统----节选
  10. JN5169_EEPROM_PDM
  11. Golang——从入门到放弃
  12. Web服务器及性能优化
  13. 江苏2021高考成绩查询全省排名,江苏省高考排名对应大学-江苏考生位次查询(2021年参考)...
  14. vscode 插件推荐 - 献给所有前端工程师
  15. 史上最全《JMeter压力测试教程》——通俗易懂,3天即可学会
  16. 使用SubstanceDesign和Unity插件ShaderForge制作风格化火焰
  17. arm 2022.10.24
  18. 正则表达式、常用的匹配总结
  19. Kubernetes安装系列之kubctl exec权限设定
  20. 已解决:小程序本地可以上传,正式发布就不行了(wx.uploadFile接口)

热门文章

  1. 没有计算器的日子怎么过——手动时期的计算工具
  2. DOX-HMDN-PEI 阿霉素-二氧化锰-聚乙烯亚胺/PEI-g-PLO(DCA) 聚鸟氨酸-聚乙烯亚胺
  3. 基于wakeup_source的linux内核睡眠机制
  4. 研发基于GUI的随机数据生成工具(V4.0完整版:设置新窗口显示数据并写入文本文件)
  5. Centos 上使用mmsh协议听猫扑网络电台 VLC播放器
  6. 聚合数据iOS SDK 12306火车票查询订票演示示例
  7. 计算机网络专业就业压力,网络工程专业就业形势研究
  8. 读取计算机内存卡,手机内存卡无法读取怎么办 读取手机内存卡详细方法【详细步骤】...
  9. 【萧蕊冰】ui设计和交互设计的区别是什么?
  10. java 标点符号_java的标点符号