MySQL学习笔记3——条件查询和聚合函数

news2024/11/15 21:54:37

条件查询和聚合函数

  • 一、条件查询语句
  • 二、聚合函数
    • 1、SUM()
    • 2、AVG()、MAX()、MIN()
    • 3、COUNT()

一、条件查询语句

WHERE 和 HAVING 的区别:

  • WHERE是直接对表中的字段进行限定,来筛选结果;
  • HAVING则需要跟分组关键字GROUP BY一起使用,通过对分组字段或分组计算函数进行限定,来筛选结果。

虽然它们都是对查询进行限定,却有着各自的特点和适用场景。

WHERE

WHERE关键字的特点是,直接用表的字段对数据集进行筛选。如果需要通过关联查询从其他的表获取需要的信息,那么执行的时候,也是先通过WHERE条件进行筛选,用筛选后的比较小的数据集进行连接。这样一来, 连接过程中占用的资源比较少,执行效率也比较高。

HAVING

HAVING不能单独使用,必须要跟GROUP BY 一起使用。

我们可以把GROUP BY理解成对数据进行分组,方便我们对组内的数据进行统计计算。

它们两个典型的区别就是:

  • 如果需要通过连接从关联表中获取需要的数据,WHERE 是先筛选后连接,而HAVING是先连接后筛选。
  • WHERE可以直接使用表中的字段作为筛选条件,但不能使用分组中的计算函数作为筛选条件;HAVING必须要与GROUP BY配合使用,可以把分组计算的函数和分组字段作为筛选条件。

这决定了,在需要对数据进行分组统计的时候,HAVING 可以完成WHERE不能完成的任务。这是因为,在查询语法结构中,WHERE在GROUP BY之前,所以无法对分组结果进行筛选。HAVING在GROUP BY之后,可以使用分组字段和分组中的计算函数,对分组的结果集进行筛选,这个功能是WHERE无法完成的。

这么说可能不太好理解,举个小例子理解一下。假如超市经营者提出,要查询一下是哪个收银员、在哪天卖了2单商品。

这种必须先分组才能筛选的查询,用WHERE语句实现就比较难,我们可能要分好几步,通过把中间结果存储起来,才能搞定。但是用HAVING,则很轻松,代码如下:

SELECT
	a. transdate, c.operatorname
FROM 
	demo. transactionhead AS a
JOIN
	demo. transactiondetails AS b ON (a. transactionid = b. transactionid)
JOIN
	demo.operator AS C ON (a.operatorid = c. operatorid)
GROUP BY a. transdate, c. operatorname
HAVING count(*)=2; 	--销售了2单

不过需要注意的是,WHERE和HAVING也不是互相排斥的,也可以在一 个查询里面同使用WHERE和HAVING。

二、聚合函数

MySQL中有5种聚合函数较为常用,分别是:

  • 求和函数SUM)
    可以返回指定字段值的和。
  • 求平均函数AVG()
  • 最大值函数MAX()
  • 最小值函数MIN()
  • 计数函数COUNT()

先创建三个表,基于这三个表的基础上对聚合函数进行操作理解:

-- 创建销售明细表
CREATE TABLE demo.transactiondetails
(
transactionid INT NOT NULL,
itemnumber INT NOT NULL,
quantity INT,
price DECIMAL(10,2),
salesvalue DECIMAL(10,2),
-- 联合主键
PRIMARY KEY(transactionid,itemnumber)
);

销售明细表(transactiondetails):
在这里插入图片描述
销售单头表(transactionhead):
在这里插入图片描述
商品信息表(goodmaster):
在这里插入图片描述

1、SUM()

SUM () 函数可以返回指定字段值的和。我们可以用它来获得用户某个门店,每天、每种商品的销售总计数据:

SELECT
	LEFT(b.transdate, 10),  -- 从关联表获取交易时间,并且通过LEFT函数,获取交易的年月日
	c.goodsname,					  -- 从关联表获取商品名称
	SUM(a.quantity),				-- 数量求和
	SUM(a.salesvalue)				-- 金额求和
FROM
	demo.transactiondetails a
		JOIN
	demo.transactionhead b ON (a.transactionid = b. transactionid)
		JOIN
	demo.goodmaster c ON (a.itemnumber = c.itemnumber)
GROUP BY LEFT(b.transdate,10), c.goodsname				-- 分组
ORDER BY LEFT(b.transdate,10), c.goodsname;				-- 排序

查询结果:
在这里插入图片描述

这里引入了两个关键字:

  • LEFT(str, n):表示返回字符串str最左边的n个字符。
  • ORDER BY:表示按照指定的字段排序。

需要注意的是,求和函数获取的是分组中的合计数据,所以要对分组的结果有准确的把握,否则就很容易搞错。这也就是说,我们要知道是按什么字段进行分组的。

  • 如果是按多个字段分组,就要知道字段之间有什么样的层次关系;
  • 如果是按照以字段作为变量的某个函数进行分组的,就要知道这个函数的返回值是什么,返回值又是如何影响分组的等。

2、AVG()、MAX()、MIN()

AVG()
首先,我们来学习下计算平均值的函数AVG ()。它的作用是,通过计算分组内指定字段值的和,以及分组内的记录数,算出分组内指定字段的平均值。
举个例子,如果用户需要计算每天、每种商品,平均一次卖出多少个、多少钱,这个时候,我们就可以用到AVG () 函数了如下所示:

SELECT
	LEFT(a. transdate,10),
	c.goodsname,
	AVG (b.quantity),		-- 平均数量
	AVG (b.salesvalue)		-- 平均金额
FROM
	demo. transactionhead a
		JOIN
	demo. transactiondetails b ON (a.transactionid = b.transactionid)
		JOIN
	demo. goodmaster c ON (b.itemnumber = c.itemnumber )
GROUP BY LEFT(a. transdate,10) ,c.goodsname
ORDER BY LEFT(a. transdate,10) ,c.goodsname;

查询结果:
在这里插入图片描述
MAX()、MIN()
MAX()表示获取指定字段在分组中的最大值,MIN()表示获取指定字段在分组中的最小值。它们的实现原理差不多。

我们还是来看具体的例子。假如户要求计算每天里的一次销售的最大数量和最大金额,就可以用下面的代码,得到我们需要的结果

SELECT
	LEFT(a. transdate,10),
	MAX(b.quantity),
	MAX(b.salesvalue)
FROM
	demo. transactionhead a
		JOIN
	demo. transactiondetails b ON (a.transactionid = b.transactionid)
		JOIN
	demo. goodmaster c ON (b.itemnumber = c.itemnumber )
GROUP BY LEFT(a. transdate,10) ,c.goodsname
ORDER BY LEFT(a. transdate,10) ,c.goodsname;

注意,MAX (字段)这个函数返回分组集中最大的那个值。如果你要查询MAX (字段1)和MAX (字段2),而它们是相互独立、分别计算的,千万不要想当然地认为结果在同一条记录上。

3、COUNT()

通过COUNT (),我们可以了解数据集的大小,这对系统优化十分重要。

比如分页策略,这个策略能够实现的一个关键,就是要计算出符合条件的记录一共有多少条,之后才能计算出一共有几页、能不能翻页或跳转。

要计算记录数,就要用到COUNT()函数了。这个函数有两种情况。

  • COUNT (*) :统计一共有多少条记录;
  • COUNT (字段) :统计有多少个不为空的字段值。

COUNT (*)
如果COUNT (*)与GROUP BY 一起使用,就表示统计分组内有多少条数据。它也可以单独使用,这就相当于数据集全体是一个分组,统计全部数据集的记录数。

那么,如果超市经营者想知道,每天、每种商品都有几次销售,我们就需要按天、按商品名称,进行分组查询:

SELECT
	LEFT(a.transdate, 10), c.goodsname, COUNT(*) -- 统计销售次数
FROM
	demo. transactionhead a
		JOIN
	demo. transactiondetails b ON (a.transactionid = b.transactionid)
		JOIN
	demo. goodmaster c ON (b.itemnumber = c.itemnumber )
GROUP BY LEFT(a. transdate,10) ,c.goodsname
ORDER BY LEFT(a. transdate,10) ,c.goodsname;

运行结果:
在这里插入图片描述

COUNT (字段)
COUNT (字段)用来统计分组内这个字段的值出现了多少次。如果字段值是空,就不统计。
在这里插入图片描述
针对这个表:

  • 如果我们要统计字段"cashierNo" 出现了多少次,就要用到函数COUNT (cashierNo), 结果是3次;
  • 如果我们要统计字段"memberId" 出现了多少次,就要用到函数COUNT (memberId), 结果是1次。

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

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

相关文章

BUG:vue表单验证校验不报错,必填都有信息,就是不能正常往下进行

vue表单验证未报错却出现异常 框架bug场景解决办法 框架 UI:element-UI 前端:vue2 bug场景 正常表单里面,有的信息要求必填或者加了一些限制,作为校验验证,只有走到校验才会执行其他行为,比如调用保存接…

在 Linux 终端中创建目录

目录 ⛳️推荐 前言 在 Linux 中创建一个新目录 创建多个新目录 创建多个嵌套的子目录 测试你的知识 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站 前言 在本系列的这一部…

微服务之CircuitBreaker断路器

一、概述 1.1背景 在一个分布式系统中,每个服务都可能会调用其它的服务器,服务之间是相互调用相互依赖。假如微服务A调用微服务B和微服务C,微服务B和微服务C又调用其他的微服务。这就是构成所谓“扇出”。 如果扇出的链路上某个微服务的调…

【详细的Kylin使用心得】

🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…

【任务调度】Apache DolphinScheduler快速入门

Apache DolphinScheduler基本概念 概念:分布式、去中心化、易扩展的可视化DAG工作流任务调度系统。 作用:解决数据处理流程中错综复杂的依赖关系,使调度系统在数据处理流程中开箱即用。Apache DolphinScheduler是一款开源的调度工具&#xff…

高仿小米商城用户端

高仿小米商城用户端(分为商城前端(tongyimall-vue)和商城后端(tongyimall-api)两部分),是Vue SpringBoot的前后端分离项目,用户端包括首页门户、商品分类、首页轮播、商品展示、商品推荐、购物车、地址管理、下订单、扫码支付等功能模块。 …

邮箱群组是什么?怎么创建邮箱群组?

在我们群发邮件时,可能会遇到这样的状况,一个个输入邮箱地址效率很低,而且很容易就漏发。而对于一个企业来说,如果出现这样的问题,很有可能会影响公司的业务进展和团队协作。这个时候我们就需要邮箱群组这个功能&#…

spring cloud介绍

Spring Cloud是一系列框架的集合,它旨在简化构建分布式系统的过程。基于Spring Boot的快速配置和管理,Spring Cloud为微服务架构提供了全面的基础设施支持。它包括但不限于以下组件: 1. **Spring Cloud Discovery** - 服务发现组件&#xff0…

MySQL行级锁——技术深度+1

引言 本文是对MySQL行级锁的学习,MySQL一直停留在会用的阶段,需要弄清楚锁和事务的原理并DEBUG查看。 PS:本文涉及到的表结构均可从https://github.com/WeiXiao-Hyy/blog中获取,欢迎Star! MySQL行级锁 行级锁(Row-…

并发学习28--多线程 Fork、Join线程池

概念 使用 import java.util.concurrent.ForkJoinPool; import java.util.concurrent.RecursiveTask;public class TC51 {public static void main(String[] args) {//递归到最小不可分解单元,再进行计算ForkJoinPool pool new ForkJoinPool(5);pool.invoke(new My…

短视频素材在哪下载?优质视频素材APP下载

在这个视频内容日益成为关键传播手段的时代,选择正确的视频素材可以极大地增强你的内容影响力。无论是制作广告、社交媒体内容还是电影制作,高质量的视频素材都是不可或缺的。以下是精心挑选的全球顶级视频素材网站列表,每个网站都能为你的视…

嵌入式4-18

做一个简单数据库终端操作系统 #include <myhead.h> int main(int argc, const char *argv[]) {int id;char name[16];float score;sqlite3 *pNULL;if(sqlite3_open("./my.db",&p)!SQLITE_OK){printf("sqlite3_open error\n");return -1;} …

QT Webengine开发过程报错qml: Render process exited with code 159 (killed)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、解决方法二、补充说明总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 基于QT的Webengine开发过程中&#xff0c;QT的官方示例…

C语言进阶课程学习记录-函数指针的阅读

C语言进阶课程学习记录-函数指针的阅读 5个标识符含义解析技巧 本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程&#xff0c;图片全部来源于课程PPT&#xff0c;仅用于个人学习记录 5个标识符含义解析 int (*p1) (int* , int (*f) ( int* ) );定义了指针p1,指向函数&#…

面试题:一个 URL 在浏览器被输入到页面展现的过程中发生了什么

文章目录 前言一、回答二、深入追问 前言 这是一段~ 经典的旋律 ~&#xff0c;不好意思串台了&#xff0c;哈哈&#xff0c;这是一个经典的面试题&#xff1a;一个URL从浏览器到页面的过程中发生了什么&#xff0c;那么今天就带大家九浅一深来研究一下 觉得不错的同学可以加我…

RocketMQ 02 功能大纲介绍

RocketMQ 02 主流的MQ有很多&#xff0c;比如ActiveMQ、RabbitMQ、RocketMQ、Kafka、ZeroMQ等。 之前阿里巴巴也是使用ActiveMQ&#xff0c;随着业务发展&#xff0c;ActiveMQ IO 模块出现瓶颈&#xff0c;后来阿里巴巴 通过一系列优化但是还是不能很好的解决&#xff0c;之后…

SAP SD学习笔记06 - 受注的据否,受注的理由,简易变更(一括处理)

上文讲了一括处理和Block&#xff08;冻结&#xff09;处理。 SAP SD学习笔记05 - SD中的一括处理&#xff08;集中处理&#xff09;&#xff0c;出荷和请求的冻结&#xff08;替代实现承认功能&#xff09;-CSDN博客 本章继续讲SAP的流程中一些常用的操作。 1&#xff0c;受注…

计算机网络练习-计算机网络体系结构与参考模型

计算机网络分层结构 ----------------------------------------------------------------------------------------------------------------------------- 1.在ISO/OSI参考模型中&#xff0c;实现两个相邻结点间流量控制功能的是( )。 A.物理层 B. 数据链路层 C.网络层 D.传…

Nougat项目学习

简介 论文学习 https://arxiv.org/abs/2308.13418 项目地址 GitHub - facebookresearch/nougat: Implementation of Nougat Neural Optical Understanding for Academic Documents 项目主页 Nougat 这个项目主要是实现将pdf文档图片转换为markdown格式&#xff1b;针对纯英…

【蓝桥杯2025备赛】素数判断:从O(n^2)到O(n)学习之路

素数判断:从O( n 2 n^2 n2)到O(n)学习之路 背景:每一个初学计算机的人肯定避免不了碰到素数&#xff0c;素数是什么&#xff0c;怎么判断&#xff1f; 素数的概念不难理解:素数即质数&#xff0c;指的是在大于1的自然数中&#xff0c;除了1和它本身不再有其他因数的自然数。 …