MySQL修炼手册4:分组与聚合:GROUP BY与HAVING的应用

news2025/2/26 1:23:36

写在开头

MySQL数据库的强大功能为我们提供了丰富的数据处理工具,其中GROUP BY与HAVING的应用使得数据的分组与聚合变得更加灵活和高效。在本篇博客中,我们将深入研究GROUP BY与HAVING的基础知识,并通过实际案例,展示它们在数据分析中的强大威力。

创建水果销售表

首先,为了更好地演示GROUP BY与HAVING的应用,我们创建了一个水果销售表fruit_sales,包含字段:id(销售记录ID)、fruit_name(水果名称)、sales_year(销售年份)、sales_quantity(销售量)、sales_revenue(销售额)。下面是一些示例数据:

CREATE TABLE fruit_sales (
    id INT PRIMARY KEY,
    fruit_name VARCHAR(50),
    sales_year INT,
    sales_quantity INT,
    sales_revenue DECIMAL(10, 2)
);

INSERT INTO fruit_sales (id, fruit_name, sales_year, sales_quantity, sales_revenue) VALUES
(1, 'Apple', 2022, 100, 150.00),
(2, 'Orange', 2022, 120, 180.00),
(3, 'Banana', 2022, 80, 90.00),
(4, 'Apple', 2023, 150, 225.00),
(5, 'Orange', 2023, 90, 108.00),
(6, 'Banana', 2023, 120, 144.00),
(7, 'Apple', 2024, 80, 120.00),
(8, 'Orange', 2024, 110, 132.00),
(9, 'Banana', 2024, 100, 120.00);

运行下面语句,查询所有数据。

SELECT
	* 
FROM
	fruit_sales;

查询所有数据:
009

1 GROUP BY子句基础

1.1 基本的GROUP BY语法

GROUP BY子句是MySQL中用于对结果进行分组的关键。通过以下语法,我们可以按照指定列的值将结果分组:

SELECT fruit_name
FROM fruit_sales
GROUP BY fruit_name;

1.2 在SELECT中使用聚合函数

与GROUP BY结合使用聚合函数,可以对每个分组进行更详细的统计分析:

SELECT
	fruit_name,
	AVG( sales_quantity ) AS avg_quantity,
	SUM( sales_revenue ) AS total_revenue 
FROM
	fruit_sales 
GROUP BY
	fruit_name;

2 常见聚合函数

2.1 COUNT函数:统计行数

COUNT函数用于统计指定列中的行数,适用于对数据集大小进行直观认识。在这里介绍三种常见的写法:
写法1:count(字段)

SELECT COUNT(id) AS total_sales

写法2:count(1)

SELECT COUNT(1) AS total_sales

写法3:count(*)

SELECT COUNT(*) AS total_sales

2.2 SUM函数:求和

通过SUM函数,我们可以计算某一列的总和,比如计算水果的总销售额:

SELECT
	SUM( sales_revenue ) AS total_revenue 
FROM
	fruit_sales;

2.3 AVG函数:求平均值

AVG函数用于计算某一列的平均值,例如计算水果的平均销售数量:

SELECT
	AVG( sales_quantity ) AS avg_quantity 
FROM
	fruit_sales;

2.4 其他常见函数

MAX(): 用于获取某列的最大值。

SELECT MAX(sales_quantity) FROM fruit_sales;

MIN(): 用于获取某列的最小值。

SELECT MIN(sales_quantity) FROM fruit_sales;

GROUP_CONCAT(): 用于将组内的值连接成字符串。

SELECT
	GROUP_CONCAT( fruit_name ) fruits_category
FROM
	fruit_sales 
GROUP BY
	sales_year;

STD() 和 STDDEV(): 分别用于计算总体标准差和样本标准差。

SELECT
	std( sales_quantity ) sales_quantity_std
FROM
	fruit_sales;
	
	SELECT
	stddev( sales_quantity ) sales_quantity_stddev
FROM
	fruit_sales;

VAR_POP() 和 VAR_SAMP(): 分别用于计算总体方差和样本方差。

SELECT
	var_pop( sales_quantity ) sales_quantity_var
FROM
	fruit_sales;
	
SELECT
	var_samp( sales_quantity ) sales_quantity_varsamp
FROM
	fruit_sales;

3 GROUP BY子句的应用

在MySQL中,GROUP BY子句是进行分组操作的关键工具,它允许我们按照指定的列对结果进行分类,从而进行更加细致的数据分析。接下来,我们将深入研究GROUP BY子句的不同应用场景,并列举一些实际的例子。

3.1 对结果进行分组

基本的GROUP BY语法已经在前文中介绍过,这里我们来看一些更具体的例子。

3.1.1 按照年份分组统计水果销售量

SELECT sales_year, SUM(sales_quantity) AS total_quantity
FROM fruit_sales
GROUP BY sales_year;

这个查询会将销售表按照年份分组,计算每年的总销售量。

3.1.2 按照水果种类和年份分组统计销售额

SELECT fruit_name, sales_year, SUM(sales_revenue) AS total_revenue
FROM fruit_sales
GROUP BY fruit_name, sales_year;

这个查询将销售表按照水果种类和年份两个维度进行分组,计算每种水果每年的总销售额。

3.2 稍微复杂一些的聚合

结合GROUP BY和聚合函数,我们可以在分组的基础上对每个分组进行各种统计操作,以下是一些示例。

3.2.1 计算每年平均销售量和总销售额

SELECT sales_year, AVG(sales_quantity) AS avg_quantity, SUM(sales_revenue) AS total_revenue
FROM fruit_sales
GROUP BY sales_year;

这个查询会计算每年的平均销售量和总销售额。

3.2.2 查找每种水果的最大销售量和最小销售额

SELECT fruit_name, MAX(sales_quantity) AS max_quantity, MIN(sales_revenue) AS min_revenue
FROM fruit_sales
GROUP BY fruit_name;

这个查询会找出每种水果的最大销售量和最小销售额。

4 聚合函数的条件运用

在实际的数据分析过程中,经常需要根据特定条件对数据进行聚合分析。聚合函数的条件运用主要通过在聚合函数内部结合使用WHERE子句和HAVING子句来实现,让我们深入探讨各种应用场景。

4.1 示例:统计每个水果在销售年份为2023年的销售量

SELECT fruit_name, SUM(sales_quantity) AS total_quantity
FROM fruit_sales
WHERE sales_year = 2023
GROUP BY fruit_name;

在这个例子中,WHERE子句用于筛选出销售年份为2023年的数据,然后通过SUM函数计算每个水果的总销售量。

4.2 示例:计算销售额超过100的水果的平均销售量

SELECT fruit_name, AVG(sales_quantity) AS avg_quantity
FROM fruit_sales
WHERE sales_revenue > 100
GROUP BY fruit_name;

在这个例子中,WHERE子句用于筛选出销售额超过100的数据,然后通过AVG函数计算每个水果的平均销售量。

5 HAVING子句的应用

在MySQL中,HAVING子句通常用于对GROUP BY的结果进行条件过滤。它在很大程度上类似于WHERE子句,但WHERE用于过滤行,而HAVING用于过滤组。下面我们将详细展开HAVING的应用,并列举一些实际场景中的使用案例。

5.1 在GROUP BY的基础上使用HAVING

当我们通过GROUP BY对数据进行分组后,有时候希望进一步筛选出符合特定条件的组,这时就需要使用HAVING子句。以下是一个简单的例子:

SELECT sales_year, fruit_name, AVG(sales_quantity) AS avg_quantity
FROM fruit_sales
GROUP BY sales_year, fruit_name
HAVING avg_quantity > 100;

在这个例子中,我们首先按年份和水果名称对数据进行了分组,然后使用HAVING筛选出平均销售数量超过100的组。

5.2 HAVING与聚合函数的进一步结合

HAVING经常与聚合函数一起使用,以便更精细地过滤分组。以下是一个例子,我们想找出销售额最高的水果,但只考虑那些销售额总和超过500的水果:

SELECT fruit_name, SUM(sales_revenue) AS total_revenue
FROM fruit_sales
GROUP BY fruit_name
HAVING total_revenue > 500;

这个查询首先按水果名称分组,然后计算每个组的销售额总和,最后通过HAVING过滤出总销售额超过500的水果。

5.3 多条件的HAVING过滤

HAVING也可以使用多个条件进行过滤,从而更灵活地满足复杂的查询需求。例如,我们想找出在2023年和2024年都有销售记录的水果:

SELECT fruit_name, COUNT(DISTINCT sales_year) AS years_with_sales
FROM fruit_sales
GROUP BY fruit_name
HAVING years_with_sales = 2;

这个查询中,我们首先按水果名称分组,然后使用COUNT(DISTINCT sales_year)计算每个组中不同年份的销售记录数量,最后通过HAVING过滤出年份数量为2的水果,即在2023年和2024年都有销售记录的水果。

5.4 HAVING与其他条件的结合

在实际应用中,HAVING通常与其他条件一起使用,以进一步精炼查询结果。例如,我们想找出在2022年以后有销售记录的水果中,销售额总和超过200的水果:

SELECT fruit_name, SUM(sales_revenue) AS total_revenue
FROM fruit_sales
WHERE sales_year >= 2022
GROUP BY fruit_name
HAVING total_revenue > 200;

这个查询中,我们首先使用WHERE条件筛选出销售年份在2022年及以后的数据,然后按水果名称分组,并通过HAVING进一步过滤出销售额总和超过200的水果。

5.5 HAVING与聚合函数的嵌套

在某些情况下,我们可能需要对聚合函数的结果再次进行聚合,这时HAVING与聚合函数的嵌套就派上用场了。例如,我们想找出每个水果销售量的平均值超过所有水果平均销售量的水果:

SELECT fruit_name, AVG(sales_quantity) AS avg_quantity
FROM fruit_sales
GROUP BY fruit_name
HAVING avg_quantity > (SELECT AVG(sales_quantity) FROM fruit_sales);

这个查询中,我们首先按水果名称分组,计算每个组的销售量平均值,然后通过HAVING子句筛选出平均销售量超过所有水果平均销售量的水果。

6 GROUP BY与多表查询的结合使用

在实际的数据库应用中,数据通常存储在多个表中,因此对这些表进行联合查询并进行适当的分组是非常普遍的操作。GROUP BY与多表查询的结合使用能够为我们提供更深入的数据分析和统计能力。

6.1 使用GROUP BY对多表进行分组

在涉及多表查询时,GROUP BY可以帮助我们对结果进行更有意义的分组。考虑以下示例,我们有一个水果销售表fruit_sales和一个水果类别表fruit_categories

CREATE TABLE fruit_categories (
    id INT PRIMARY KEY,
    fruit_name VARCHAR(50),
    category VARCHAR(50)
);



INSERT INTO fruit_categories (id, fruit_name, category) VALUES
(1, 'Apple', 'hard'),
(2, 'Orange', 'soft'),
(3, 'Banana', 'soft');

现在,我们想要按照水果类别进行销售量的统计,可以使用如下查询:

SELECT
	fc.category,
	SUM( fs.sales_quantity ) AS total_quantity 
FROM
	fruit_sales fs
	JOIN fruit_categories fc ON fs.fruit_name = fc.fruit_name 
GROUP BY
	fc.category;

这个查询将fruit_salesfruit_categories两个表联合起来,按照水果类别进行分组,然后计算每个类别的总销售量。这对于分析不同类别水果的整体销售表现非常有帮助。

6.2 GROUP BY与JOIN操作的协同应用

在多表查询中,JOIN操作和GROUP BY可以协同使用,为我们提供更为复杂的数据统计和分析。考虑以下场景,我们要找出每个水果类别的平均销售额:

SELECT
	fc.category,
	AVG( fs.sales_revenue ) AS avg_revenue 
FROM
	fruit_sales fs
	JOIN fruit_categories fc ON fs.fruit_name = fc.fruit_name 
GROUP BY
	fc.category;

这个查询首先通过JOIN将fruit_salesfruit_categories两个表关联,然后按照水果类别进行分组,最后计算每个类别的平均销售额。这样的查询可以为市场策略制定、库存管理等方面提供重要的数据支持。

写在最后

通过本篇MySQL修炼手册,我们深入研究了GROUP BY与HAVING的应用,以及它们在不同场景下的运用技巧。掌握这些知识,将使我们在实际应用中更加游刃有余地处理复杂的数据分析与统计任务。在下一篇手册中,我们将继续拓展MySQL的强大功能,探讨更多高级查询与优化技巧,为数据库操作的深入理解打下坚实基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1383068.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

select...for update锁详解

select…for update锁详解 select…for update的作用就是:如果A事务中执行了select…for update,那么在其提交或回滚事务之前,B,C,D…事务是无法操作(写)A事务select…for update所命中的数据的…

游戏找不到emp.dll,无法运行的5种解决方法

游戏在运行过程中提示找不到emp.dll文件,这一现象的原因可能涉及到多个层面。首先,emp.dll是一个动态链接库文件,对于特定的游戏运行至关重要,它可能包含了游戏运行所必需的函数、资源或其他关键信息。当系统在加载游戏时无法找到…

【AI】Pytorch 系列:预训练模型使用

1. 模型下载 import re import os import glob import torch from torch.hub import download_url_to_file from torch.hub import urlparse import torchvision.models as modelsdef download_

k8s云原生环境搭建笔记——第二篇

目录 1、使用普通方式安装prometheus和grafana1.1、安装kube-state-metrics容器1.1.1、下载并修改yaml文件1.1.2、导入kube-state-metrics镜像1.1.3、执行yaml文件目录 1.2、安装node-exploer1.2.1、创建名称空间prometheus1.2.2、执行yaml 1.3、安装prometheus1.3.1、创建集群…

【洛谷千题详解】P1980 [NOIP2013 普及组] 计数问题

#include<bits/stdc.h> using namespace std; int main() {int n,x,ans0;cin>>n>>x;for(int i1;i<n;i){int numberi;while(number){int anumber%10;number/10;if(ax) ans;}}cout<<ans<<endl;return 0; }

ssm基于java的自助医疗服务系统的设计与实现+jsp论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本自助医疗服务系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

代码随想录 Leetcode142. 环形链表 II

题目&#xff1a; 代码(首刷看解析 2024年1月13日&#xff09;&#xff1a; class Solution { public:ListNode *detectCycle(ListNode *head) {if (head nullptr) return nullptr;ListNode* fast head;ListNode* slow head;while (true) {if(fast->next nullptr || fa…

DICE模型的原理与推导、碳循环与气候变化、政策评估、不确定性分析与代码分析

目录 专题一&#xff1a;DICE模型的原理与推导 专题二&#xff1a;碳循环与气候变化 专题三&#xff1a;政策评估 专题四&#xff1a;不确定性分析与代码分析 更多应用 随着温室气体排放量的增大和温室效应的增强&#xff0c;全球气候变化问题受到日益的关注。我国政府庄严…

函数栈桢的创建和销毁

函数栈桢的创建和销毁 一、解决的问题二、认识常用的寄存器及其指令操作三、函数栈桢解析三、回答问题 一、解决的问题 1.局部变量是怎么创建的&#xff1f;  2.为什么局部变量的值是随机值&#xff1f;  3.函数是怎么传参的&#xff1f;传参的顺序是怎样的&#xff1f;  4.…

漏洞修复整理

一、Geoserver Apache HTTP/2拒绝服务漏洞&#xff08;CVE-2023-44487&#xff09;、Eclipse Jetty 资源管理错误漏洞(CVE-2023-26048)、Eclipse Jetty 信息泄露漏洞(CVE-2023-26049) 受影响版本&#xff1a;9.4.53以下版本 处理方式&#xff1a;原地升级 &#xff08; jdk版本…

Vue3 如何使用移动端调试工具vConsole

1、安装 pnpm i vconsole2、在src/utils下新建vconsole.ts&#xff0c;写入以下代码 // 这是移动端控制台调试工具&#xff0c;需要调试就打开,不用就注释 import vConsole from vconsole const vconsole new vConsole()3、src/main.ts 引入&#xff0c;需要调试就打开,&…

熊猫电竞赏金电竞系统源码 APP+H5双端 附搭建教程 支持运营级搭建

简介: 熊猫电竞赏金电竞系统源码 APP+H5双端 附搭建教程 支持运营级搭建 可搭建!运营级!首次公开! 赏金赛源码,用户通过平台打比赛,赢了获得奖金奖励, 金币赛、赏金赛、vip赛等种赛事 可开王者荣耀、和平精英比赛 支持1v1、单排、双排组、战队排等多种比赛模式 …

手写springBoot启动器

提示&#xff1a;springboot原理&#xff0c;手写springboot启动器&#xff0c;手写模拟SpringBoot启动过程、手写模拟SpringBoot自动配置功能 文章目录 前言一、本文内容1、手写模拟SpringBoot启动过程2、手写模拟SpringBoot自动配置功能 二、项目总体介绍三、代码实现(手写模…

Adobe Illustrator 2023--AI2023中文

Adobe Illustrator 2023是一款专业的矢量图形设计软件&#xff0c;广泛应用于印刷、Web、视频和移动设备的设计制作。它提供了丰富的绘图工具、矢量图形编辑功能和灵活的排版设计工具&#xff0c;帮助用户快速高效地制作出精美的设计作品。相较于其他设计软件&#xff0c;Adobe…

分享7款前端CSS动画特效源码(附在线演示)

精选7款前端CSS动画特效源码 下面我会给出特效样式图或演示效果图 但你也可以点击在线预览查看源码的最终展示效果及下载源码资源 CSS飞行的荷包蛋 CSS荷包蛋动画 荷包蛋会向右前方加速飞行 期间还能看到周围的气流匆匆飞过 以下图片只是简单的模型没有具体的动画效果最终动画…

Python读取log文件报错“UnicodeDecodeError”

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 问题描述&#xff1a; 写了一个读取log文件的Python脚本&#xff1a; # -*- coding:utf-8 -*- import os import numpy as np …

手撕乘积(**Multiplication** **Product**): 穷举和图示(1)

手撕乘积(Multiplication & Product): 穷举和图示(1) 乘积 r ⋅ s ∑ i 1 s r r r ⋯ r ⏟ s times ∑ j 1 r s s s ⋯ s ⏟ r times r\cdot s\sum _{i1}^{s}r\underbrace {rr\cdots r} _{s{\text{ times}}}\sum _{j1}^{r}s\underbrace {ss\cdots s} _{r{\tex…

怎么把workspace的数据导入到simulink查看波形?

仿真截图&#xff1b; 示例代码&#xff1a; sampleTime 0.001; %设置采样时间 numSteps 1/sampleTimes; %设置时间矩阵长度 time sampleTime*(0:numSteps-1); %定义时间矩阵 time time; %时间矩阵转置 data sin…

【Maven】008-Maven 私服搭建与使用

【Maven】008-Maven 私服搭建与使用 文章目录 【Maven】008-Maven 私服搭建与使用一、概述1、简介2、建立私服后依赖查找和下载逻辑第一步&#xff1a;请求本地仓库第二步&#xff1a;请求 Maven 私服第三步&#xff1a;请求外部远程仓库&#xff08;远程中央仓库等&#xff09…

SOMEIP学习总结

SOMEIP学习总结&#xff08;包含VSOMEIP库&#xff09; 一.基本概念 1.SOMEIP支持TCP和UDP两种传输方式 ​ 其中&#xff0c;SOMEIP-SD的消息都是通过UDP发送的 2.SOMEIP支持如下中间件特性&#xff1a; Serialization – transforming into and from on-wire representati…