MySQL_表_进阶(2/2)

上一章我们谈了排序子句,使用ORDER BY 字段 DESC/ASC。以及左右连接的多关系查询。

今天,没错,四张表最后两个需求 ✨涉及聚合函数查询与指定别名


四张表:

  学院表:(testdb.dept)

课程表:(testdb.course)

选课表:(testdb.sc)

学生表 :(testdb.stu)

需求如下:

  1. 查询每个学生的总成绩,显示学号、姓名、总成绩,列名以中文显示。
  2. 查询每门课程的选课人数,显示课程编号、课程名称、选课人数,没有学生选的课程也要显示,按选课人数降序排列。(提示:选课人数需要计算)

 需求一:

 查询每个学生的总成绩,显示学号、姓名、总成绩,列名以中文显示。

 我们看到一个要求,也算闻所未闻:列名以中文显示。A,你发现,原来查询出来的结果表还可以自己命名列名。

这其实是对字段的取别名操作:

“列名以中文显示”——给字段名指定别名

我们在SELECT 语句后往往加上我们想要的字段,这时候,往往结果查出来的列表头就是字段名。

比如:我们查询学号为“2022121001”的学生的选课信息,要求显示他的学号,姓名和所选课程编号。

SELECT sc.stuid,stuname,cid
FROM testdb.sc
JOIN testdb.stu
ON stu.stuid = sc.stuid AND sc.stuid = '2022121001';
#因为stuname属于stu表,所以需要联合查询
#一连就发现,两张表都有stuid这个字段,因此,每个stuid前都需要加前缀。

最后显示的结果:

 

你可以看到,列表头,就是我们刚刚select语句要求显示的字段名:stuid,stuname,cid。

有些时候,为了更好的理解显示的信息,我们会为显示的字段指定别名。你想,stuid我若是原先不说是学生学号,其实是要反应时间的。取成中文,理解成本就会大大降低。

怎么取呢?

SELECT 字段 AS 别名
FROM ...
....

刚刚,显示的学生学号,姓名,课程编号,我全部取别名就是这样:

SELECT sc.stuid AS 学号,stuname AS 姓名,cid AS 选课课程号
FROM testdb.sc
JOIN testdb.stu
ON stu.stuid = sc.stuid AND sc.stuid = '2022121001';

效果如下:

需求分析:

显示学号,姓名没问题,就是这个总成绩......看起来有点问题,testdb.sc表(选课表)是有score(成绩)这个字段,但不是总成绩。

要显示总成绩,按照我们自己的逻辑:我们会把相同学号的几行合成一行,然后行的最后显示几个score的总和,这个总和就是他们的总成绩。

比如:学号2022121004这个同学,下表中他有两行记录,那么最后显示的结果,学号 姓名 总成绩

2022121004 李四 188

这个188就是把学号都是2022121004的score记录都加起来的

 选课表:(testdb.sc)

对于这种,SQL内部提供了许多聚合函数: 

常见的聚合函数
函数名称功能
AVG按列计算平均值
SUM按列计算值的总和
MAX求一列中的最大值
MIN求一列中的最小值
COUNT按列值统计个数

我们这里要计算“总成绩”,明显是要用这里的SUM,但是这个“按列”,就很有说法了。

按谁的列,按照什么来划分?

我们要求显示,每个同学的总成绩,testdb.sc(选课表)表里体现同学的,就只有stuid(学号)。那得出结论:按照相同的学号来分组,每个组内都使用聚合函数(此处是sum),得到就是每个同学的总成绩。

分组的关键字:GROUP BY 加字段名(作为分组的依据)

代码就是这样写的:

SELECT sc.stuid AS 学号,stuname AS 姓名,SUM(score) AS 总成绩
FROM testdb.sc
#这里的总成绩调用的聚合函数,函数自然是需要参数,传进去的就是单个成绩
#主要的表还是sc表,但是stuname这个字段是来自stu表,还需要联合
GROUP BY sc.stuid
#按照学生学号来分组,相同学号的不同学科成绩进行聚合,就是咱们的总成绩

 添加联合查询:

SELECT sc.stuid AS 学号,stuname AS 姓名,SUM(score) AS 总成绩
FROM testdb.sc
JOIN testdb.stu
ON stu.stuid = sc.stuid
GROUP BY sc.stuid;

所以,这个需求的代码就如上显示。

需求二:

查询每门课程的选课人数,显示课程编号、课程名称、选课人数,没有学生选的课程也要显示,按选课人数降序排列。(提示:选课人数需要计算)

这怎么也算咱们最后一个需求,这里咱们换个思路:这次真正的先写框架——把学过的都用起来

SELECT cid,cname,选课人数
FROM testsdb.sc
#说“选课人数”,姑且就从sc表选

这里的选课人数,应该就是数有多少个学生,sc表中使用stuid来代表一个学生。我们使用COUNT这个计数函数。

SELECT cid,cname,COUNT(stuid)
FROM testsdb.sc
#这里迟迟定不下cid前面的前缀,是因为course表也有这个字段,最后再来补充也不迟

 因为cname这个字段属于course表,所以这里还需要联合查询。但是联合查询:有普通的JOIN,亦有左右连接,你又该怎么选呢?

SELECT cid,cname,COUNT(stuid)
FROM testsdb.sc
JOIN testdb.course
ON course.cid = sc.cid
#连表的条件还是相同的字段就行

继续读题: "没有学生选的课程也要显示"。我们这里若只是简单地使用默认的JOIN查询,它能达到的效果只是匹配两表都存在,返回两个表中有匹配的行。

若使用JOIN连接,一些course表里有的课程,但是在sc里没有被学生选(也就是说,sc表里没有记录)。这种课程,是无法匹配的,最后的结果也不会保留这种没被选的课的记录。

我们为了保持某一张的完整性,往往会采取左右连接,选出主表。这里既然要保证所有课程信息都在,那么,那张被保存下来的表应该就是course表。破案了,所以在上述代码,应该有右连接course表。

SELECT cid,cname,COUNT(stuid)
FROM testsdb.sc
RIGHT JOIN testdb.course
ON course.cid = sc.cid

现在来分组,既然是每个课程的选课人数,分组条件就是课程 ——把选同一门课程的stuid分为一组,COUNT函数对stuid进行计数,得到的结果就是该门课的选课人数。

SELECT cid,cname,COUNT(stuid)
FROM testsdb.sc
RIGHT JOIN testdb.course
ON course.cid = sc.cid
GROUP BY course.cid
#cid的前缀在确定主表的那一刻就注定了:在sc表可能并不存在,但是course里是一定有的。一旦两表的cid匹配不上,sc.cid会为NULL,但course.cid始终有效

注意:GROUP BY子句里面的分组字段,应该是尽力包含所有的SELECT语句的字段(聚合函数除外)。

不同的课程id也有其对应的课程名称cname,将它俩都作为分组条件,才是最推荐(原则上,是视具体问题而定)。你想,条件越细化,其结果的偏差就会越小。

所以,GROUP BY子句里面应该包含SELECT 语句的cid, 它俩具有绑定性。既然course.cid在course(主表)能保证数据的完整和有效,GROUP BY里使用course.cid,那SELECT 里的cid也应该来自testdb.course。

SELECT course.cid,cname,COUNT(stuid)
FROM testsdb.sc
RIGHT JOIN testdb.course
ON course.cid = sc.cid
GROUP BY course.cid

哈哈哈修文:我又回来了,我忽然想起来,这个需求还需要我们降序显示(🤐) 

所以:

SELECT course.cid,cname,COUNT(stuid)
FROM testsdb.sc
RIGHT JOIN testdb.course
ON course.cid = sc.cid
GROUP BY course.cid
ORDER BY COUNT(stuid) DESC;
#按选课人数进行降序排列

 注:在查询语句中,我们学了WHERE语句,GROUP BY 分组语句,ORDER BY语句。三者的执行顺序:WHERE语句(用于指定查询,联合查询)GROUP BY(搭配聚合函数),ORDER BY(对查询结果排序),ORDER BY 子句必须出现在其他子句之后。

小总结: 

本节重点:聚合函数 指定显示字段别名

需求一参考代码:

#查询每个学生的总成绩,显示学号、姓名、总成绩,列名以中文显示。
SELECT sc.stuid AS 学号,stuname AS 姓名,SUM(score) AS 总成绩
FROM testdb.sc
JOIN testdb.stu
ON stu.stuid = sc.stuid
GROUP BY sc.stuid;

 需求二参考代码:

#查询每门课程的选课人数,显示课程编号、课程名称、选课人数,没有学生选的课程也要显示,按选课人数降序排列。(提示:选课人数需要计算)
SELECT course.cid,cname,COUNT(stuid)
FROM testsdb.sc
RIGHT JOIN testdb.course
ON course.cid = sc.cid
GROUP BY course.cid
ORDER BY COUNT(stuid) DESC;

这次的左右连接的实践,相信你又对其应用的了解更上一层楼,四张表的应用——从创建表、到数据的增删查改,终于...OVER了(🍵)但是,对表的细节学习,我们不会停下,毕竟:

学无止境也,然则问可少耶

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

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

相关文章

Rust编程的if选择语句

【图书介绍】《Rust编程与项目实战》-CSDN博客 《Rust编程与项目实战》(朱文伟,李建英)【摘要 书评 试读】- 京东图书 (jd.com) Rust编程与项目实战_夏天又到了的博客-CSDN博客 Rust语言实现选择结构时,根据某种条件的成立与否而采用不同的程序段进行…

【VUE】axios组件

1. 快速使用 npm install axiosLoginView.vueimport axios from "axios" axios.get("...") axios.post("...") axios.axios({method: "get" })2. 通用配置 npm install axiosplugins/axios.jsimport axios from "axios";l…

基于nodejs+vue的农产品销售管理系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏:Java精选实战项目…

C++学习笔记----8、掌握类与对象(一)---- 对象中的动态内存分配(4)

2.4、使用Move语法处理移动 类的move语法要求一个move构造函数和一个move赋值操作符。这些可以用于编译器,当源对象是一个临时对象在操作完成时就会被析构,你马上就会看到,显式地使用std::move()。move移动内存的属主以及从一个对象到另一个对…

FortiGate 无线组网

无线管理与配置 FortiAP 连接 internal 接口之后自动获得 ip 地址:192.168.1.xxx/24在 FortiGate 中创建 SSIDFortiGate 自动发现 FortiAP,将 FortiAP 添加到 FortiGate将 SSID 和 FortiAP 关联创建防火墙策略 下面我们就来一起看看在 FortiGate 中该如…

ModbusTCP通讯错误的排查

Modbus是一种由MODICON公司开发的工业现场总线协议标准,是一项应用层报文传输协议。该协议用于传输数字和模拟变量[1]。有关该协议的报文具体格式,以及一些基本概念,见[1]。 本文以一个例子,阐述当ModbusTCP通讯出现错误的时候&a…

开源鸿蒙OpenHarmony系统更换开机Logo方法,瑞芯微RK3566鸿蒙开发板

本文适用于开源鸿蒙OpenHarmony系统更换开机Logo,本次使用的是触觉智能的Purple Pi OH鸿蒙开源主板,搭载了瑞芯微RK3566芯片,类树莓派设计,是Laval官方社区主荐的一款鸿蒙开发主板。 介绍 OpenHarmony的品牌标志、版本信息、项目…

计算机毕业设计 基于Hadoop的智慧校园数据共享平台的设计与实现 Python 数据分析 可视化大屏 附源码 文档

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…

探索EasyCVR视频融合平台:在视频编解码与转码领域的灵活性优势

随着视频监控技术的飞速发展,各类应用场景对视频数据的处理需求日益复杂多样。从公共安全到智慧城市,再到工业监控,高效、灵活的视频处理能力成为衡量视频融合平台性能的重要标准。在众多解决方案中,EasyCVR视频融合平台凭借其在视…

大觅网之自动化部署(Automated Deployment of Da Mi Network)

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…

音视频整体解码流程和同步流程

目录 1. 整体解码流程1. 初始化 FFmpeg2. 打开媒体文件3. 查找解码器4. 打开解码器5. 读取和解码数据6. 处理解码后的帧7. 释放资源 2. 音视频同步整体流程1. 解复用媒体流2. 解码3. 以音频为时钟源进行音视频同步的策略4. 缓冲区设计 现在先说大体流程,不分析代码 …

使用python爬取豆瓣网站?如何简单的爬取豆瓣网站?

1.对python爬虫的看法 首先说说我对python的看法,我的专业是大数据,我从事的工作是java开发,但是在工作之余,我对python又很感兴趣,因为我觉得python是一门很好的语言,第一:它可以用来爬取数据…

如何使用 Rust 框架进行 RESTful API 的开发?

一、RESTful API 的开发 使用 Rust 框架进行 RESTful API 开发,你可以选择多种流行的 Rust Web 框架,如 Actix-web、Rocket、Warp 和 Tide 等。以下是使用这些框架进行 RESTful API 开发的基本步骤和概念: 选择框架:根据项…

DRF笔记

一、CBV与FBV FBV(Function-Based Views) # views.py from django.shortcuts import HttpResponse from django.views.decorators.csrf import csrf_exemptcsrf_exempt def book_views(request):if request.method "GET":return HttpRespo…

区块链—共享块存储安全可信任可追踪分布式数据库系统技术

审核不过?这里面没有广告 为什么被识别为广告? 什么是区块链? 区块链是一种不可篡改的共享分类账,有助于推动业务网络中记录交易和跟踪资产的过程。 资产可以是有形的(房屋、汽车、现金、土地)&#xff…

探索 Snowflake 与 Databend 的云原生数仓技术与应用实践 | Data Infra NO.21 回顾

上周六,第二十一期「Data Infra 研究社」在线上与大家相见。活动邀请到了西门子数据分析师陈砚林与 Databend 联合创始人王吟,为我们带来了一场关于 Snowflake 和 Databend 的技术探索。Snowflake,这个市值曾超过 700 亿美元的云原生数据仓库…

李宏毅机器学习2023-HW10-Adversarial Attack

文章目录 TaskBaselineFGSM (Fast Gradient Sign Method (FGSM)I-FGSM(Iterative Fast Gradient Sign Method)MI-FGSM(Momentum Iterative Fast Gradient Sign Method)M-DI2-FGSM(Diverse Input Momentum Iterative Fast Gradient Sign Method) Reportfgsm attackJepg Compress…

性能优化与资源管理:优化Selenium脚本的执行效率,合理管理浏览器实例和系统资源

目录 引言 一、Selenium基础与常用方法 1.1 Selenium简介 1.2 Selenium基础用法 二、Selenium性能优化技巧 2.1 使用WebDriverWait实现显式等待 2.2 启用无头模式 2.3 设置合理的页面加载策略 2.4 禁用图片和JavaScript加载 2.5 优化元素定位 2.6 合理使用隐式等待和…

国产化框架PaddleYOLO结合Swanlab进行作物检测

1. 项目介绍 粮食安全,作为人类生存与发展的基石,始终是全球关注的焦点。它不仅仅关乎粮食的充足供应,更涉及粮食的质量安全、营养健康以及可持续生产等多个维度。在全球化、气候变化和资源环境约束日益加剧的背景下,如何确保粮食…

Node-GDAL:简洁强大的Node.js地理空间数据处理库

一、简介 node-gdal是Node.js环境下的一个强大库,它是GDAL(Geospatial Data Abstraction Library)的原生绑定库。GDAL是一个开源的地理空间数据处理库,用于读写多种栅格和矢量地理空间数据集。node-gdal允许开发者在Node.js环境中…