【数据库】MySQL的聚合查询,联合查询及关键字的执行顺序

news2024/12/23 15:00:05

目录

1.聚合查询

1.1聚合函数

1.2GROUP BY子句

1.3HAVING

2.联合查询

联合查询步骤

2.1内连接

2.2外连接

2.3自连接

2.4子查询

单行子查询

多行子查询

2.5合并查询

UNION

UNION ALL

3.SQL关键字的使用顺序

3.1语法顺序

3.2执行顺序


1.聚合查询

聚合查询是SQL语句。它通过包含一个聚合函数(如 Sum 或 Avg )来汇总来自多个行的信息。

补充:聚合函数会忽略NULL值。

1.1聚合函数

常见的统计总数、计算平局值等操作,可以使用聚合函数来实现,常见的聚合函数如下表:
函数 说明
COUNT([DISTINCT] expr) 返回查询到的数据的数量
SUM([DISTINCT] expr) 返回查询到的数据的总和,不是数字没有意义
AVG([DISTINCT] expr) 返回查询到的数据的平均值,不是数字没有意义
MAX([DISTINCT] expr)
返回查询到的数据的 最大值,不是数字没有意义
MIN([DISTINCT] expr) 返回查询到的数据的 最小值,不是数字没有意义

示例:

这里准备了一个学生表和一个成绩表。

select * from student;
select * from exam_result;

1.COUNT函数

查询学生表中数据的数量

-- 写0和写*效果一样
select count(*)from student;
select count(0)from student;

结果为5条,NULL不会统计在内

 统计id有多少个,结果为5

select count(id)from student;

2.SUM函数

统计数学成绩总分

select sum(math)from exam_result;

3.AVG函数

统计平均总分

select avg(chinese+math+english)from exam_result;

4.MAX函数

返回英语最高分

SELECT MAX(english) FROM exam_result;

5.MIN函数

返回70分以上的数学最低分

SELECT MIN(math) FROM exam_result WHERE math > 70;

1.2GROUP BY子句

SELECT中使用GROUPBY子句可以对指定列进行分组查询。需要满足:使用GROUPBY进行分组查询时,SELECT指定的字段必须是“分组依据字段”,其他字段若想出现在SELECT 中则必须包含在聚合函数中。
语法:

select column1, sum(column2), .. from table group by column1,column3; 

示例:

准备测试表

create table emp(
id int primary key auto_increment,
name varchar(20) not null,
role varchar(20) not null,
salary numeric(11,2)
);
insert into emp(name, role, salary) values
('马云','服务员', 1000.20),
('马化腾','游戏陪玩', 2000.99),
('孙悟空','游戏角色', 999.11),
('猪无能','游戏角色', 333.5),
('沙和尚','游戏角色', 700.33),
('隔壁老王','董事长', 12000.66),
('王聪','游戏陪玩',9999.00),
('雅子','服务员',3544.90)
;

查询每个角色的最高工资,最低工资和平均工资:

1.首先要按照角色(role)进行分组

2.再通过聚合函数查询最高,最低和平均工资。

select role,max(salary),min(salary),avg(salary) from emp group by role; 

1.3HAVING

GROUP BY子句进行分组以后,需要对分组结果进行条件过滤时,不能使用WHERE语句,需要使用HAVING。

例如:

显示平均工资低于1500的角色和它的平均工资。

1.先按照角色进行分组

2.分组之后查找工资低于1500的角色

3.通过聚合函数算出这些角色的平均工资

select role,avg(salary) as 平均工资 from emp  group by  role having avg(salary)<1500 ;

2.联合查询

联合查询是可合并多个相似的选择查询的结果集。等同于将一个表追加到另一个表,从而实现将两个表的查询组合到一起。使用条件查询所需要的数据。

实际开发中往往数据来自不同的表,所以需要多表联合查询。多表查询是对多张表的数据取笛卡尔积(全排列):

笛卡尔乘积是指在数学中,两个集合X和Y的笛卡尓积(Cartesian product),又称直积,表示为X*Y,第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员  。

假设集合A={a, b},集合B={0, 1, 2},则两个集合的笛卡尔积为{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}。

用一些例子来看看联合查询到底是什么?

初始化测试数据:

classes表

create table classes(name varchar(255),learning varchar(255));
insert into classes(name, learning) values
('计算机系2019级1班', '学习了计算机原理、C和Java语言、数据结构和算法'),
('中文系2019级3班','学习了中国传统文学'),
('自动化2019级5班','学习了机械自动化');

student表

drop table student;
create table student(id int,name varchar(255),email varchar(255),classes_id int);
insert into student(id, name, email, classes_id) values
('09982','黑旋风李逵','xuanfeng@qq.com',1),
('00835','菩提老祖',null,1),
('00391','白素贞',null,1),
('00031','许仙','xuxian@qq.com',1),
('00054','不想毕业',null,1),
('51234','好好说话','say@qq.com',2),
('83223','tellme',null,2),
('09527','老外学中文','foreigner@qq.com',2);

course表

drop table course;
create table course(id int,name varchar(255));
insert into course(id,name) values
(1,'Java'),(2,'中国传统文化'),(3,'计算机原理'),(4,'语文'),(5,'高阶数学'),(6,'英文');

score表

create table score(score int,student_id int,course_id int);
insert into score(score, student_id, course_id) values
-- 黑旋风李逵
(70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6),
-- 菩提老祖
(60, 2, 1),(59.5, 2, 5),
-- 白素贞
(33, 3, 1),(68, 3, 3),(99, 3, 5),
-- 许仙
(67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6),
--  不想毕业
(81, 5, 1),(37, 5, 5);

各表如下图所示:

联合查询步骤

1.先确定查询的数据在哪些表中

2.做一个笛卡尔积(全排列)

3.根据关联字段把无效数据过滤掉

4.根据业务需求使用where等关键字对有效数据行进行过滤

5.精简查询字段

2.1内连接

内连接(INNER JOIN)主要通过设置连接条件的方式,来移除查询结果中某些数据行的交叉连接。简单来说,就是利用条件表达式来消除交叉连接的某些数据行。
内连接使用 INNER JOIN 关键字连接两张表,并使用 ON 子句来设置连接条件。

语法:

select 字段 from 表1 别名1 [inner] join 表2 别名2 on 连接条件 and 其他条件;
select 字段 from 表1 别名1,表2 别名2 where 连接条件 and 其它条件;

例如:

1.查询‘许仙’同学的成绩:

通过连接student表和score表,查询许仙的成绩。

select sco.score from student stu inner join score sco on stu.id=sco.student_id
and stu.name='许仙';
-- 或者
select sco.score from student stu, score sco where stu.id=sco.student_id and
stu.name='许仙';

2.查询所有同学的总成绩以及个人信息:

成绩表对学生表是多对1关系,查询总成绩是根据成绩表的同学id来进行分组的
SELECT
stu.sn,
stu.NAME,
stu.qq_mail,
sum( sco.score )
FROM
student stu
JOIN score sco ON stu.id = sco.student_id
GROUP BY
sco.student_id; 

3.查询所有同学的成绩及个人信息

-- 查询出来的都是有成绩的同学,“老外学中文”同学 没有显示
select * from student stu join score sco on stu.id=sco.student_id;
-- 学生表、成绩表、课程表3张表关联查询
SELECT
stu.id,
stu.sn,
stu.NAME,
stu.qq_mail,
sco.score,
sco.course_id,
cou.NAME
FROM
student stu
JOIN score sco ON stu.id = sco.student_id
JOIN course cou ON sco.course_id = cou.id
ORDER BY
stu.id; 

2.2外连接

外连接分为三种:左外连接,右外连接,全外连接。会返回每个满足第一个(顶端)输入与第二个(底端)输入的联接的行。它还返回任何在第二个输入中没有匹配行的第一个输入中的行。

左外连接:如果在连接查询中,连接管子左端的表中所有的元组都列出来,并且能在右端的表中找到匹配的元组,那么连接成功。如果在右端的表中,没能找到匹配的元组,那么对应的元组是空值(NULL)。

右外连接:与左外连接类似,只是右端表中的所有元组都列出,限制左端表的数据必须满足连接条件,而不管右端表中的数据是否满足连接条件,均输出表中的内容。

通俗易懂的说,就是如果联合查询,左侧的表完全显示我们就说是左外连接,右侧的表完全显示我们就说是右外连接。

语法:

-- 左外连接,表1完全显示
select 字段名  from 表名1 left join 表名2 on 连接条件;
-- 右外连接,表2完全显示
select 字段 from 表名1 right join 表名2 on 连接条件;

例如:

查询所有同学的成绩及同学的个人信息,如果该同学没有成绩,也需要显示。

-- “老外学中文”同学 没有考试成绩,也显示出来了
select * from student stu left join score sco on stu.id=sco.student_id;
-- 对应的右外连接为:
select * from score sco right join student stu on stu.id=sco.student_id;
-- 学生表、成绩表、课程表3张表关联查询
SELECT
 stu.id,
 stu.sn,
 stu.NAME,
 stu.qq_mail,
 sco.score,
 sco.course_id,
 cou.NAME
FROM
 student stu
 LEFT JOIN score sco ON stu.id = sco.student_id
 LEFT JOIN course cou ON sco.course_id = cou.id
ORDER BY
 stu.id;

2.3自连接

自连接是指在同一张表中连接自身进行查询。把列转换为行,从而实现数据之间的运算。

例如:

显示所有‘计算机原理’比‘Java’成绩高的成绩信息。

步骤:

1.找到涉及的表:course表和score表,从course表中找出对应的课程编号

select * from course;

2.从score表中找出对应的课程成绩,保证s1.course_id=3 and s2.course_id=1  and s1.student_id=s2.student_id。

select * from score s1,score s2;

select * from score s1,score s2 where s1.course_id=3 and s2.course_id=1 and s1.student_id=s2.student_id;

 

3. 查询‘计算机原理’比‘Java’成绩高的成绩信息,即s1.score>s2.score。

select * from score s1,score s2 where s1.course_id=3 and s2.course_id=1 and s1.student_id=s2.student_id and s1.score>s2.score;

全部代码如下:

-- 先查询“计算机原理”和“Java”课程的id
select id, name from course where name="计算机原理"or name="java";

-- 再查询成绩表中,“计算机原理”比“Java”成绩高的信息
select s1.*
from
score s1,score s2
where s1.student_id=s2.student_id
and s1.score<s2.score
and s1.course_id=1
and s2.course_id=3;

-- 也可以使用join on 语句来进行自连接查询
SELECT
 s1.* 
FROM
 score s1
 JOIN score s2 ON s1.student_id = s2.student_id
 AND s1.score < s2.score
 AND s1.course_id = 1
 AND s2.course_id = 3;
以上查询只显示了成绩信息,并且是分布执行的。要显示学生及成绩信息,并再一条语句显示:
SELECT
 stu.*,
 s1.score Java,
 s2.score 计算机原理
FROM
 score s1
 JOIN score s2 ON s1.student_id = s2.student_id
 JOIN student stu ON s1.student_id = stu.id
 JOIN course c1 ON s1.course_id = c1.id
 JOIN course c2 ON s2.course_id = c2.id
 AND s1.score < s2.score
 AND c1.NAME = 'Java'
 AND c2.NAME ="计算机原理";

2.4子查询

子查询,就是在一个查询中嵌套了其它查询,一个查询的条件依赖于另一个查询的结果。

单行子查询

返回一行记录的子查询。

例如:

查询“不想毕业”同学的同班同学。

按照之前的方法可以分两步查询:

1.找到涉及的表:student表,找到不想毕业在哪个班

select classes_id from student where name="不想毕业";

 2.查询这个班中名字不为“不想毕业”的同学

select * from student where classes_id="1"and name!="不想毕业";

使用子查询一步就到位:

select * from student where classes_id=(select classes_id from student where name="不想毕业");

多行子查询

返回多行记录的子查询。

1.关键字[NOT]IN,在in这个范围内, 如果符合这个范围内的条件,则输出对应的记录。

例如:查询“语文”或“英语”课程的成绩信息

select * from score where course_id in(select id from course where name="语文"or name="英文");

2.关键字[NOR]EXIST,EXISTS用于检查是否至少会返回一行数据,该子查询实际上并不返回任

何数据,而是返回True或False。

例如:

-- 使用 EXISTS
select * from score sco where exists (select sco.id from course cou 
where (name='语文' or name='英文') and cou.id = sco.course_id);
-- 使用 NOT EXISTS
select * from score sco where not exists (select sco.id from course cou 
where (name!='语文' and name!='英文') and cou.id = sco.course_id);

2.5合并查询

在实际应用中,为了合并多个select的执行结果,可以使用集合操作符UNION,UNION ALL。使用时,前后查询的结果集中,字段需要一致。

UNION

该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果中的重复行。

例如:

查询id大于3,或者名字为“英文”的课程。

前者查询结果为:

select * from course where id>3;

后者查询结果为:

select * from course where name="英文";

 使用union查询结果为:

UNION ALL

该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果中的重复行。

例如:

查询id大于3,或者名字为“英文”的课程。

select * from course where id>3 union all select * from course where name="英语";

3.SQL关键字的使用顺序

3.1语法顺序

  • select[distinct]  
  • from  
  • join(如left join)  
  • on  
  • where  
  • group by  
  • having  
  • union  
  • order by  
  • limit 

3.2执行顺序

  1. from  
  2. on  
  3. join  
  4. where  
  5. group by  
  6. having  
  7. select  
  8. distinct  
  9. union  
  10. order by  

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

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

相关文章

快速将PDF转换为图片:使用在线转换器的步骤

PDF文件是一种常见的文档格式&#xff0c;但在某些情况下需要将其转换为图片格式&#xff0c;例如将PDF文件插入PPT演示文稿中。此时&#xff0c;使用在线PDF转换器是一种快速且简便的方法。 本文将介绍如何使用在线转换器将PDF文件转换为图片格式。 步骤1&#xff1a;选择合…

Three.js+TypeScript+Webpack学习记录(三)

使用环境参考 Node.js v16.19.1 正文 独立功能文件 我们不可能一直在 index.ts 中写代码&#xff0c;分离文件&#xff1a; // init.ts import * as THREE from threeexport const initScene () > {const scene new THREE.Scene()scene.background new THREE.Color(wh…

【多线程】Java中是如何保证多线程间的数据共享的?

文章目录 前言一、Java的内存模型二、保证可见性的方式volatilesynchronizedlockfinal 三、volatile的底层实现总结 前言 在讨论这个问题之前&#xff0c;我们可以先瞅瞅Java的内存模型JMM&#xff0c;JMM可不要和JVM混为一谈。我们说的是内存模型JMM&#xff08;Java Memory …

JavaSE-06 [面向对象OOP + 封装]

JavaSE-06 [面向对象OOP 封装] 第一章 面向对象思想 1.1 面向过程和面向对象 面向过程&#xff1a; 面向过程就是分析出解决问题所需要的步骤&#xff0c;然后用函数把这些步骤一步一步实现&#xff0c;使用的时候一个一个依次调用就可以了面向对象&#xff1a; 面向对象是…

博弈论(NIM游戏——取石子)相关的题目

1.异或的性质 &#x1f3f3;️‍&#x1f308;&#x1f3f3;️‍&#x1f308;&#x1f3f3;️‍&#x1f308;&#x1f3f3;️‍&#x1f308;&#x1f3f3;️‍&#x1f308;&#x1f3f3;️‍&#x1f308; 2.nim游戏 &#xff08;基础&#xff09; 891. Nim游戏 - AcWin…

直播软件app开发:如何处理直播延迟问题?

随着直播技术的发展&#xff0c;直播软件app的开发变得越来越普遍。然而&#xff0c;直播延迟问题一直是直播软件app开发中的一个挑战。在本文中&#xff0c;我们将探讨如何解决直播延迟问题&#xff0c;提高用户体验。 直播延迟的原因 直播延迟的原因是多方面的。其中最主要…

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

文章目录 一、MyCat 概览1.1 简介1.2 官网网址1.3 仓库地址1.4 Mycat1.x 与 Mycat2 功能对比1.5 下载1.5.1 先决条件1.5.2 Mycat2 安装包&#xff08;以下二选一&#xff09; 1.6 Mycat2权威指南1.7 原型库什么是兼容性 SQL&#xff1f;什么是 Prototype 服务器&#xff1f;原型…

shell第二次作业

一、编写脚本for1.sh使用for循环创建20账户&#xff0c;账户名前缀由用户从键盘输入&#xff0c;账户初始密码由用户输入。 1、创建脚本for1.sh [rootlocalhost ~]# vim for1.sh2、编辑脚本内容 3.运行 [rootlocalhost ~]# bash for1.sh 请用户输入账户名的前缀&#xff1a…

WPS AI 再次引爆办公软件行业,以后写文档可由AI代笔

国内外办公软件两大巨头聚齐&#xff0c;使用AI助力再次成标配。 2023年3月16日&#xff0c;微软发布了 Microsoft 365 Copilot&#xff0c;Microsoft 365 这个名字听起来比较陌生&#xff0c;它集成了Office 365 企业版、Windows 10 企业版以及企业移动性安全性&#xff0c;以…

基于Jira的持续交付流水线实践方式

点击上方蓝字⭐️关注“DevOps云学堂”&#xff0c;接收最新技术实践 今天是「DevOps云学堂」与你共同进步的第 19 天 DevOps 为什么很重要&#xff1f; 软件和 Internet 改变了我们身处的世界&#xff0c;同时也改变了购物、娱乐、银行等行业的运营方式。软件不再仅仅是为业务…

【unity项目实战】3DRPG游戏开发03—— 绘制low poly风格的场景

搭建场景 拖入一颗树,按住V键,表示顶点吸附,点击树的底部,他就会自动吸附到相邻的平面上了 如果你的摄像机位置不是很好,我们可以场景移动到合适的位置,可以点击摄像机,按下键盘ctrl+shift+F同步调整摄像机位置 绘制low poly风格的环境 安装Ploybrush插件,并导入样…

linux安装南大通用数据库 GBase 8s V8.8

linux安装南大通用数据库 GBase 8s V8.8 1、操作系统、数据库2、下载链接3、安装文档4、安装前准备4.1、以root用户创建 gbasedbt 组和用户4.2、创建 GBase 8s 数据库安装目录4.3、上传并解压安装包 5、安装5.1、执行安装程序5.2、回车继续 直到接受许可条款5.3、输入安装目录绝…

Windows安装使用Redis,redis基本使用教程,python连接调用redis

文章目录 下载&#xff1a;安装&#xff1a;redis安装成Windows服务&#xff1a;修改密码&#xff1a;客户端连接&#xff1a;基本使用&#xff1a;python里调用redis&#xff1a; 下载&#xff1a; https://github.com/microsoftarchive/redis/releases/tag/win-3.2.100 安装…

机器学习:基于多项式贝叶斯对蘑菇毒性分类预测分析

基于多项式贝叶斯对蘑菇毒性分类预测分析 作者&#xff1a;i阿极 作者简介&#xff1a;Python领域新星作者、多项比赛获奖者&#xff1a;博主个人首页 &#x1f60a;&#x1f60a;&#x1f60a;如果觉得文章不错或能帮助到你学习&#xff0c;可以点赞&#x1f44d;收藏&#x1…

银行数字化转型导师坚鹏:银行业务数字化创新工作坊

银行业务数字化创新工作坊 课程背景&#xff1a; 很多银行存在以下问题&#xff1a; 不清楚如何进行业务数字化创新&#xff1f; 不知道如何开展银行数字化营销工作&#xff1f; 不知道零售业务数字化创新成功案例&#xff1f; 学员收获&#xff1a; 学习原创银行BLM…

【音视频】国际双向对讲方案

语音对讲的的整体流程为&#xff1a; 先拉流播放设备的视频&#xff1b;使用WebRTC推送语音流到ZLM服务&#xff1b;使用SIP协议下发Broadcast指令给设备&#xff1b;接收到设备的OK指令后&#xff0c;请求ZLM的startSendRtp接口&#xff0c;TCP协议请求startSendRtpPassive接口…

springboot集成webmagic和selenium,并部署到linux(问题坑)

springboot集成webmagic和selenium&#xff0c;并部署到linux&#xff08;问题坑&#xff09; 首先参考两个源代码spring boot集成找不到org.openqa.selenium.remote.AbstractDriverOptions的类文件代理ip--更换一个网页同时更换一个代理ip代理ip网址部署linux谷歌浏览器下载谷…

Python冒泡排序的实现

时间复杂度&#xff1a; 最坏时间复杂度O(n^2) 最优时间复杂度O(n):表遍历一次发现没有任何可以交换的元素&#xff0c;排序结束&#xff0c;这是最理想的 稳定性&#xff1a;稳定&#xff0c;&#xff08;执行前后没有对数据没有变化&#xff0c;位置等&#xff09; 原理和方…

供需两端催化口腔医疗服务市场增长 未来将呈现线上化、智能化、品质化三大趋势

一、口腔医疗服务行业概述 口腔由唇、颊、舌、腭、涎腺、牙和颌骨等部分组成。口腔疾病种类繁多&#xff0c;伴随人全生命周期&#xff0c;常见疾病有龋病、牙周疾病、牙髓病、根尖周病、牙齿缺损、错颌畸形等&#xff0c;多数口腔疾病的发病率高&#xff0c;诊疗需求大。除此…

深度强化学习——策略学习(3)

本文的重点&#xff1a;使用一个神经网络来近似策略函数Π 我们使用一个神经网络来近似策略函数&#xff0c;这个神经网络叫做策略网络&#xff0c;他可以用来控制agent运动&#xff0c;想要训练这个神经网络&#xff0c;就要用到policy gradient算法 策略函数Π的输入是当前…