[mysql]聚合函数GROUP BY和HAVING的使用和sql查询语句的底层执行逻辑

#GROUP BY的使用

还是先从需求出发,我们现在想求员工表里各个部门的平均工资,最高工资

SELECT department_id,AVG(salary)

FROM employees

GROUP BY department_id

我们就会知道它会把一样的id分组,没有部门的就会分为一组,我们也可以用其他字段来分组,我们想查询不同jb_id的平均工资

SELECT job_id,AVG(salary)

FROM employees

GROUP BY job_id

那这个大家就了解了,还是比较容易理解的

现在我们要使用多个列分组比如我们要计算不同部门的不同工种的平均工资,也就是用job_id和department_id的平均工资

SELECT job_id,department_id,AVG(salary)

FROM employees

GROUP BY department_id, job_id

我们现在想先用job_id先分组,然后再对departmentid分组

这两个是一样的吗.答案是一样的,比如我们先把一个部门给分类,在把一个工种分类,和先把工种分类再把部门分类这个明显是相同的

刚才我们计算的时候,没有加部门和工种,字段,是为了我们的可读性来给它加上了字段,我们能不能在group,by里去掉工种只按照部门分工种

现在mysql最新版已经不支持这个写法了,因为我们用group by只对工种进行分组了,但是剩下的部门没有分,那不就没有位置放部门了

GROUP BY的结论1

我们除了聚合函数的字段,一定要出现在GROUP BY中,但是GROUPBY的字段不一定要出现在查询字段中.

GROUP BY的位置

GROUP BY必须在FROM 和WHERE的后面ORDER BY的前面和LIMIT的前面

GROUP BY的结论3新特性

Mysql中的GROUP BY的WITH ROLLUP

我们在GROUP 字段 WITH ROLLUP

现在我们是不是可以发现最后多了一行,这个数字实际上是公司的平均工资,

我们这里要小心的使用ORDER BY和 WITH ROLLUP 我们不加的话是可以进行运行,但是加入之后就会报错,这是错误的方式,但是mysql最新版已经支持这么做了.

 

我们要是出现分组了大家就应该注意到是我们要对字段进行相同值分组的时候进行.

HAVING TO的使用

我们现在多了一个HAVING TO

现在我们想查询各个部门中最高工资比10000高的部门信息.

相当于我们想查询各个部门中最高工资

要求1

SELECT后面出现的非聚合函数字段,一定要出现在GROUP BY后面

还有一件事,我们如果字段出现非聚合函数,一定要出现在GROUPBY中,这个大家一定要牢记,那么现在我们发现查询出来的结果有很多是没有超过10000的,和我们的要求不一致,比10000小的我们就不要,我们以前是只讲过WHERE 而且它必须跟在FROM后面,那么我们现在写WHERE MAX(salary)>10000,

要求2

一旦我们的过滤条件中使用的聚合函数,那么我们就必须要使用HAVING TO来替换WHERE 否则就会报错.

现在我们出现了聚合函数,或者说组函数了,我们来写一个正确的写法

不管我们学那个语言我们实际上是有很多规则的,+表示加和连接,这是规范和规则出现的,直接背就好了,就和叫爸爸叫妈妈,一样没有小孩会想为什么要这么叫,下面的东西就可以考虑深层次的原因,后面的东西我们都是可以解释的,也就是一会我们会说HAVING TO 为什么不能用WHERE,

我们把HAVING换进去,发现还是报错了,

要求2:我们要把HAVING TO 放在GROUP BY的后面

他的声明位置必须在GROUP BY的后面,写在前面了自然就错误了

这就是我们正确的情况

要求3

要是没有GROUP BY能不能使用HAVING TO 函数,发现我们是可以使用的,因为我们没有聚合函数了,我们使用的时候,最后聚合函数的结果是不是没有必要去过滤它了.我们用WHERE筛选之后,再用聚合函数之后再用HAVING就没有什么意义了

所以HAVING 要和GROUPBY一起合并使用.

现在我们要查询部门ID为10,20,30,40,4个部门最高工资比10000高的部门信息

这里前面也是一个过滤条件,我们能不能用WHERE来写,这是方式1

SELECT department_id,MAX(salary)

FROM employees

WHERE department_id IN (10,20,30,40)

GROUP BY department_id

HAVING MAX(salary)>10000

我们还能把条件写在WHERE

SELECT department_id,MAX(salary)

FROM employees

GROUP BY department_id

HAVING MAX(salary)>10000 AND department_id IN (10,20,30,40)

那么大家就会纳闷了,那么大家应该就有一个疑惑了,WHERE和HAVING有什么区别呢.

大家可以逆向思维.存在就是合理的,WHERE 里面是不能加聚合函数,那我们直接用HAVING不就好了,我们这里就会推荐大家使用方式1,因为方式1的执行效率比方式2高,,

当过滤条件中有聚合函数时间,这个过滤条件必须声明在HAVING中,没有聚合函数时,此过滤条件声明在WHERE中和HAVING都可以,建议大家声明在WHERE中

这不是同情,因为WHERE的效率高,虽然是建议,大家还是直接当成规则用了.

WHERE和HAVING的对比1从适用范围来讲HAVING的适用范围更广,HAVING可以完成聚合函数的过滤

2如果过滤函数里没有聚合函数,这种情况WHERE效率高于HAVING,开发中选择

,子查询是一个查询中套了一个查询,基本的知识点我们已经讲到,子查询只是在结构里嵌套另一个结构,所以我们可以直接开始讲SELECT 语句的结构了

SELECT语句的完整结构:

sql92语法

SELECT            (含有聚合函数)

FROM 表1,表2,表3

WHERE 多表的连接条件 AND 过滤条件,不包含聚合函数

GROUP BY 分组操作,….

HAVING 包含聚合函数的过滤条件

ORDER BY

LIMIT

sql99语法

SELECT ……(含有聚合函数)

FROM 表1 (left/right)JOIN

ON 表2

(left/right)JOIN

ON表2

WHERE 不包含 聚合函数的过滤条件

GROUP BY

HAVING

ORDER BY

LIMIT

SQL语句的执行过程

第一部分

SELECT ……(含有聚合函数)

第二部分

FROM 表1 (left/right)JOIN

ON 表2

(left/right)JOIN

ON表2

WHERE 不包含 聚合函数的过滤条件

GROUP BY

HAVING

第三部分

ORDER BY

LIMIT

正常情况我们以为是按顺序运行的,实际上我们的是先执行的第二部分,然后第一部分最后第三部分.

上来我们先FROM 表1 (left/right)JOIN

ON 表2

(left/right)JOIN

ON表2

WHERE 不包含 聚合函数的过滤条件

GROUP BY

HAVING

如下

FROM ->ON->(left/right)JOIN->WHERE->GROUP->HAVING ->SELECT->DISTINCT->ORDER BY->LIMIT

我们先找到一张表连接另一张表,进行笛卡尔交叉的连接,然后用ON来把不关联的去掉了,限制了连接的条件,这是在后台的虚拟表,每执行一步就变化一步,过滤了之后,由于可能是左外和右外的连接,,虚拟表也会进行保留,然后进行WHERE条件的过滤,保留需要的内容,然后对其中内容进行分组,分组之后我们再进行HAVING聚合函数的条件筛选,然后看看SELECT想要的是那几个字段,因为字段是全部保留之前虚拟表里,用SELECT筛选出我们要的字段,,因为这里面还有可能有DISTINCT去重的操作,再过滤一小部分,确定了最后的数据,对数据进行排序,和分页的操作

现在我们就可以解释为什么where比HAVING的数据效率高了,因为我们分组之前可能10万条数据,我们对它进行筛选了只剩下10条,然后我们分组,那是不是很简单,如果我们用的是HAVING那么就吭哧吭哧对它进行10万条分组,,最后HAVING说只要最后2个条件,那前面8万条都浪费操作了,

为什么WHERE 不能放聚合条件呢,因为我们还没分组,聚合条件根本用不了,你只能前向引用,HAVING可以向分组的GROUPBY进行计算函数,但是 WHERE不能向未来运行GROUPBY进行前向引用,这里就解释完了,

我们在SELECT中查询一个字段我们可以在ORDERBY里使用别名,但是不能再WHERE里使用,也是因为这个原因

每个过程中都会形成一个虚拟表,这就是一个执行过程,是不是感觉挺高端的,之后我们还会讲更多SQL的底层逻辑我们才能将SQL的优化问题.得知道粮食里的结构才能养生,我们要能辨别知识的结构.我们就得有一个完善的体系架构

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ArcGIS计算多个面要素范围内栅格数据各数值的面积

本文介绍在ArcMap软件中,基于面积制表工具(也就是Tabulate Area工具),基于1个面要素数据集与1个栅格数据,计算每一个面要素中各栅格数据分布面积的方法。 首先,来看一下本文的需求。现有一个矢量面的要素集…

水陆两栖车应对应急事件发挥的作用_鼎跃安全

随着气候变化,城市内涝等问题日益严重。为了应对可能出现的洪水灾害,许多城市开始将水陆两栖车纳入应急救援装备体系。在暴雨引发城市积水时,水陆两栖车可以作为一种高效的救援和运输工具,及时疏散被困群众,运送应急物…

Hallo2 长视频和高分辨率的音频驱动的肖像图像动画 (数字人技术)

HALLO2: LONG-DURATION AND HIGH-RESOLUTION AUDIO-DRIVEN PORTRAIT IMAGE ANIMATION 论文:https://arxiv.org/abs/2410.07718 代码:https://github.com/fudan-generative-vision/hallo2 模型:https://huggingface.co/fudan-generative-ai/h…

执行Django项目的数据库迁移命令时报错:(1050, “Table ‘django_session‘ already exists“);如何破?

一、问题描述: 当我们写Django时,由于自己的操作不当,导致执行数据库迁移命令时报错,报错的种类有很多,例如: 迁移文件冲突:可能你有多个迁移文件试图创建同一个表。数据库状态与迁移文件不同…

Javascript数据结构——哈希表

18_哈希表_深入链地址法_哔哩哔哩_bilibili 哈希表(Hash Table),又称为散列表,是一种通过哈希函数组织数据以实现快速访问的数据结构。下面将从其概述、底层实现和前端应用场景等方面进行详细阐述。 概述 哈希表的基本思路是&a…

C#与C++交互开发系列(九):字符串传递的几种形式

前言 在C#与C交互开发中,字符串的传递是非常常见的需求。字符串作为数据类型在托管代码(C#)和非托管代码(C)之间的传递存在一些特殊的挑战,因为两者的字符串内存管理和编码方式不同。本篇博客将详细介绍几…

gitlab不同账号间·仓库转移

背景:公司业务调整,原先在海外仓库的代码转移回国内 诉求:完整的保留项目记录 操作: 步骤一: 定位到需要迁移的原项目地址 步骤二:创建新项目 步骤三:打开命令行,创建好文件路径为需要clo…

软件工程中的建造者模式:用于构建复杂对象

在软件工程中,我们经常会遇到需要构建复杂对象的场景。这些对象可能包含多个组件,而这些组件的创建过程可能相当繁琐。为了解决这个问题,设计模式提供了一种优雅的方法,这就是建造者模式(Builder Pattern)。…

HTTP之响应消息Response

个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ HTTP之响应消息Response 1 Response 组成2 状态…

基于SpringBoot+Vue+MySQL的实践性教学系统

系统展示 用户前台界面 后台界面 系统背景 随着信息技术的快速发展,企业对于高效、智能的管理系统需求日益迫切。传统的管理系统大多采用单机版或C/S架构,存在操作复杂、维护困难、数据共享性差等问题。而基于SpringBootVueMySQL的全栈管理系统&#xff…

通信协议——UART

目录 基础概念串行&并行串行的优缺点 单工&双工 UART基本概念时序图思考:接收方如何确定01和0011 基础概念 串行&并行 串行为8车道,并行为1车道 串行的优缺点 通行速度快浪费资源布线复杂线与线之间存在干扰 单工&双工 单工&#xf…

018集——c# 实现CAD添加侧栏菜单(WPF控件)(CAD—C#二次开发入门)

本例实现的效果如下&#xff1a; 第一步&#xff1a;添加引用 using UserControl System.Windows.Controls.UserControl; using System.Windows.Forms.Integration;//PaletteSet integration 第二步 <UserControl x:Class"AcTools.UserControl1"xmlns"htt…

【数据分析】Power BI的使用教程

目录 1 Power BI架构1.1 Power BI Desktop1.2 Power BI服务1.3 Power BI移动版 2 Power Query2.1 Power Query编辑器2.2 Power Query的优点2.3 获取数据2.4 数据清洗的常用操作2.4.1 提升标题2.4.2 更改数据类型2.4.3 删除错误/空值2.4.4 删除重复项2.4.5 填充2.4.6 合并列2.4.…

【Airtest】 UI 自动化

一、环境配置 项目名称&#xff1a;Yavin 锁定python3.7.x和opencv-contrib-python3.4.2.17&#xff0c;不然各种报错 参考airtest官网https://airtest.doc.io.netease.com/ 虚拟环境配置 安装所需要的依赖包 二、框架使用方式 1.目录结构介绍 2.config文件config.yaml文…

前端开发设计模式——状态模式

目录 一、状态模式的定义和特点 二、状态模式的结构与原理 1.结构&#xff1a; 2.原理&#xff1a; 三、状态模式的实现方式 四、状态模式的使用场景 1.按钮的不同状态&#xff1a; 2.页面加载状态&#xff1a; 3.用户登录状态&#xff1a; 五、状态模式的优点 1.提…

【深度学习基础】详解Pytorch搭建CNN卷积神经网络实现手写数字识别

MNIST 数据集,其包含70000 个2828 的手写数字的数据集,其中又分为60000 个训练样本与10000 个测试样本。 安装实验用到的包 anaconda promt 安装python包, 首先在开始界面打开prompt 进入到相应的虚拟环境中,下面的python38你自己创建的虚拟环境名称。 # 激活虚拟环境,v…

Ubuntu 24.04 系统上配置 Node.js 运行环境

本文我们重点介绍两种安装 Node.js 的方法。第一种方法使用 NVM (Node VersionManager)&#xff0c;这是安装和管理多个 Node.js 版本的最好和最快的方法。第二种方法使用官方包存储库在 Ubuntu 上安装 Node.js&#xff0c;一次只允许安装一个版本。 必备条件 A running Ubun…

yarn的安装与使用以及与npm的区别(安装过程中可能会遇到的问题)

一、yarn的安装 使用npm就可以进行安装 但是需要注意的一点是yarn的使用和node版本是有关系的必须是16.0以上的版本。 输入以下代码就可以实现yarn的安装 npm install -g yarn 再通过版本号的检查来确定&#xff0c;yarn是否安装成功 yarn -v二、遇到的问题 1、问题描述…

特斯拉Optimus:展望智能生活新篇章

近日&#xff0c;特斯拉举办了 "WE ROBOT" 发布会&#xff0c;发布会上描绘的未来社会愿景&#xff0c;让无数人为之向往。在这场吸引全球无数媒体的直播中&#xff0c;特斯拉 Optimus 人形机器人一出场就吸引了所有观众的关注。从多家媒体现场拍摄的视频可以看出来&…

Ubuntu 上安装 Redmine 5.1 指南

文章目录 官网安装文档&#xff1a;命令步骤相关介绍GemRubyRailsBundler 安装 Redmine更新系统包列表和软件包&#xff1a;安装必要的依赖&#xff1a;安装 Ruby&#xff1a;安装 bundler下载 Redmine 源代码&#xff1a;安装 MySQL配置 Redmine 的数据库配置文件&#xff1a;…