数据库 SQL高级查询语句:聚合查询,多表查询,连接查询
目录
- 创建学生表
- 聚合查询
- 聚合函数
- 直接查询
- 设置别名查询
- 设置条件查询
- 常用的聚合函数
- 分组查询
- 单个字段Group by
- 报错分组查询
- 多字段分组查询
- 多表查询
- 直接查询
- 重命名查询
- Students表新建一列CourseID
- 连接(JOIN)查询
- INNER JOIN
- RIGHT JOIN, LEFT JOIN
- FULL JOIN
- 课后练习
- 复习
- 参考
创建学生表
创建Students和Courses表
CREATE TABLE Students (StudentID int PRIMARY KEY,Name varchar(255),Gender varchar(1),Age int,City varchar(255)
);
INSERT INTO Students VALUES(1, 'David', 'M', 21, 'Shanghai');
INSERT INTO Students VALUES(2, 'Kevin', 'M', 19, 'Beijing');
INSERT INTO Students VALUES(3, 'Emily', 'F', 22, 'Shanghai');
INSERT INTO Students VALUES(4, 'William', 'M', 20, 'New York City');
INSERT INTO Students VALUES(5, 'Alice', 'F', 19, 'Los Angeles');
INSERT INTO Students VALUES(6, 'Frank', 'F', 22, 'Los Angeles');
CREATE TABLE Courses (CourseID int PRIMARY KEY,CourseName varchar(255)
);
INSERT INTO Courses VALUES(1, 'CS101');
INSERT INTO Courses VALUES(2, 'CS202');
INSERT INTO Courses VALUES(3, 'EE101');
聚合查询

聚合函数
直接查询
SELECT COUNT(*) FROM Students;

设置别名查询
SELECT COUNT(*) AS StudentsNum FROM Students;
设置条件查询
使用COUNT(*) 和 COUNT(StudentID)是一样的效果,因为StudentID是主键,每行记录的主键都不同。另外我们在聚合查询中还是能使用WHERE子句的,比如我们要查找年龄大于20岁的学生数量,可使用以下SQL语句:
SELECT COUNT(*) FROM Students AS s WHERE s.age > 20;
常用的聚合函数
函数 说明
SUM 计算某一列的总和,该列必须为数值类型
AVG 计算某一列的平均数,该列必须为数值类型
MAX 计算某一列的最大值
MIN 计算某一列的最小值
查询学生的平均年龄
SELECT AVG(Age) FROM Students;
使用AVG聚合函数

分组查询
单个字段Group by
根据城市City对学生进行分组,并需要查询每个城市有多少学生
SELECT City, COUNT(*) FROM Students GROUP BY City;

报错分组查询
如果将Name也放入查询结果,会报错,因为来自相同城市的学生可能有很多位,名字各不相同,所以以下语句是不合法的:
SELECT City, COUNT(*), Name FROM Students GROUP BY City;
报错信息如下

SELECT 列表的表达式 #3 不在 GROUP BY 子句中,并且包含非聚合列“tuling.Students.Name”,该列在功能上不依赖于 GROUP BY 子句中的列;这与 sql_mode=only_full_group_by 不兼容。
#3就指的是Name那一列
多字段分组查询
GROUP BY 也能放入多个字段,比如我们想先将学生根据City分组,然后再根据性别分组,可以使用以下语句:
SELECT City, Gender, COUNT(*) FROM Students GROUP BY City, Gender;

学生表中Los Angeles的两个人性别一样,分组显示的为F,计数为2

现在我将其中一人人的性别改为M,思考一下查询结果会发生变化吗?
地点相同,性别不同的被区分出来了。

可以看到原来Los Angeles为2,现在变成了两个1,性别M和F被区分了。

多表查询
SELECT 查询除了能从单表中查数据外,也能从多表中查询数据。语法如下:
直接查询
SELECT * FROM Students, Courses;
查询结果是两个表的笛卡尔积
假设Students有5列字段和7行记录,Courses有2列字段和3行记录,其结果就是一个拥有21 (3 * 7) 行记录和 7 (5 + 2) 列字段的二维表,既Students表的每一行和Courses表的每一行两两拼在一起。结果集的列数会是两表列数之和,而行数是两表行数之积。
重命名查询
有时候两张表可能拥有相同名字的字段,那么结果则会让人疑惑,我们可以通过使用 AS 取别名来区别字段。比如使用以下语句给StudentID和CourseID改名为StudentId和CourseId:
SELECT Students.StudentID AS StudentId, Courses.CourseID AS CourseId FROM Students, Courses;
给字段取别名的语法类似 column_name AS new_column_name,上面的语句分别给StudentID和CoursesID取了别名StudentId和CourseId,虽然在这个例子中,我们只是将最后的字母D变为小写。但考虑一下另一种情况:假设Students和Courses的主键字段都叫ID,那么这个别名就很有帮助了,我们可以使用以下语句使查询结果更明了:
SELECT Students.ID AS StudentId, Courses.ID AS CourseId FROM Students, Courses;
除了给输出字段取别名外,给表格取别名也很有用的,语法类似table_name AS alias,我们可以将上面的语句写成下面这样:
SELECT S.ID AS StudentId, C.ID AS CourseId FROM Students AS S, Courses AS C;
Students表新建一列CourseID
在多表查询中,还是能使用WHERE子句。为了帮助大家理解之后的内容,我们需要给Students添加一列新的字段CourseID,代表此学生选择的课程:
新建一列CourseID在City之后
alter table Students add column CourseID int(4) not null after City;

CouseID的值设置为StudentID的值一半
update Students set CourseID = StudentID/2

查询StudentID和其对应的课程名字
SELECT S.StudentID,C.CourseName
FROM Students AS S,Courses AS C
WHERE S.CourseID = C.CourseID;

报错!!! 知道为什么吗一般 erro syntax就是中文字符的问题,
Students as S,Courses as C 这个逗号是中文字符,改成英文字符后运行成功啦

除了WHERE子句,其他子句类似ORDER BY,GROUP BY也都适用于多表查询。
除了WHERE子句,其他子句类似ORDER BY,GROUP BY也都适用于多表查询。
连接(JOIN)查询
INNER JOIN
连接查询是另一种类型的多表查询,连接查询会对多个表格进行JOIN运算。也就是说,先确定一个主表作为结果集,然后将其他表的记录有选择性地“嵌入”到主表结果集上。
假设我们想要知道每个学生选择的课程名字,除了上面提到的多表查询加WHERE子句,我们还能使用INNER JOIN子句:
SELECT S.StudentID, C.CourseName
FROM Students AS S
INNER JOIN Courses AS C ON S.CourseID = C.CourseID;

此语句就能将每个StudentID和其对应的课程名查询出来,要注意INNSER JOIN语句的内在执行过程如下:
- 1 确定主表,使用 FROM table_name
- 2 紧接着确认连接的表,使用 INNER JOIN table_name
- 3 再确定连接条件,使用 ON condition,上面语句的条件就是 S.CourseID = C.CourseID
- 4 最后还能加上 : WHERE、ORDER BY等子句
除了INNER JOIN外,我们还有LEFT JOIN, RIGHT JOIN, 和FULL JOIN。
补充:别名不是必须的,只是为了增加可读性。
RIGHT JOIN, LEFT JOIN
如果我们将语句改为 RIGHT JOIN:
SELECT S.StudentID, C.CourseName
FROM Students AS S
RIGHT JOIN Courses AS C ON S.CourseID = C.CourseID;

修改Students表格,让5,6选课程1,重新右连接查询。

执行上面的语句之后,如果有一节课没有任何学生加入,我们会有一行多余的记录,记录中仅有CourseName,但是StudentID为NULL。

为什么会这样呢?INNER JOIN 会返回同时存在两张表的数据,如果Students有1, 2, 3, 5课号,Courses也有1, 2, 3, 4课号,那么结果就是其相交集1, 2, 3。而 RIGHT JOIN 返回的则是右表存在的记录,如果左表不存在右表中的某几行,那结果中的那几行就会是NULL。
而 LEFT JOIN 则会返回左表中都存在的数,如果给Students加上CourseID=10,即使Courses表中没有ID为10的课程记录,那么LEFT JOIN的结果还是会多一行记录,其对应的CourseName是NULL。(补充:LEFT JOIN 在有些数据库中叫做 LEFT OUT JOIN,同理 RIGHT JOIN 也可能叫做 RIGHT OUT JOIN。)
FULL JOIN
最后一种 JOIN 是 FULL JOIN,结果集会把两张表的所有记录全部选出来,并自动把两张表中不存在的列补充为NULL。
为了帮助大家理解连接查询的逻辑,大家可以参看以下的图示,左边的圆可以理解为左表,右边的圆可以理解为右表。

以上就是SQL语法的基本教程啦,现在大家已经学会了如何使用 SQL 创建表格和记录,并使用高级的 SQL 语句进行复杂的查询,下一章我们就开始学习使用真正的数据库软件 MySQL。
课后练习
请写出SQL语句,找出加入CourseID为1的学生数量和课程名字,要注意的是,我们只寻找那些年纪大于20岁的男学生数量。
方法1 使用Where
SELECT COUNT(*) AS StudentsNum,CourseName
FROM Students AS S,Courses AS C
WHERE S.CourseID = C.CourseID AND S.CourseID = 1 AND S.Age > 20 AND S.Gender = 'M';
方法2 Group by + where
SELECT COUNT(*) AS StudentsNum, CourseName
FROM Students LEFT JOIN Courses ON Students.CourseID = Courses.CourseID
WHERE Students.Age > 20 AND Students.Gender = 'M'
GROUP BY Students.CourseID;
复习
- 1 确定主表,使用 FROM table_name
- 2 紧接着确认连接的表,使用 INNER JOIN table_name
- 3 再确定连接条件,使用 ON condition,上面语句的条件就是 S.CourseID = C.CourseID
- 4 最后还能加上 : WHERE、ORDER BY等子句
除了INNER JOIN外,我们还有LEFT JOIN, RIGHT JOIN, 和FULL JOIN。
参考
【SQL高级查询语句:聚合查询,多表查询,连接查询【关系数据库SQL教程5】】 https://www.bilibili.com/video/BV1Zp4y1Q7mj/?share_source=copy_web&vd_source=fe6c23f6f1353ed1eff5d5e866171572
相关文章:
数据库 SQL高级查询语句:聚合查询,多表查询,连接查询
目录 创建学生表聚合查询聚合函数直接查询设置别名查询设置条件查询 常用的聚合函数 分组查询单个字段Group by报错分组查询多字段分组查询 多表查询直接查询重命名查询Students表新建一列CourseID 连接(JOIN)查询INNER JOINRIGHT JOIN, LEFT JOINFULL J…...
pytorch-构建卷积神经网络
构建卷积神经网络 卷积网络中的输入和层与传统神经网络有些区别,需重新设计,训练模块基本一致 import torch import torch.nn as nn import torch.optim as optim import torch.nn.functional as F from torchvision import datasets,transforms impor…...
点云从入门到精通技术详解100篇-点云滤波算法及单木信息提取(续)
目录 3.3 点云滤波算法原理概述 3.3.1 坡度滤波算法 3.3.2 基于不规则三角网滤波 3.3.3 数学形态学滤波...
Gartner发布中国科技报告:数据编织和大模型技术崭露头角
近日,全球知名科技研究和咨询机构Gartner发布了关于中国数据分析与人工智能技术的最新报告。报告指出,中国正迎来数据分析与人工智能领域的蓬勃发展,预计到2026年,将有超过30%的白领工作岗位重新定义,生成式人工智能技…...
java八股文面试[数据库]——explain
使用 EXPLAIN 关键字可以模拟优化器来执行SQL查询语句,从而知道MySQL是如何处理我们的SQL语句的。分析出查询语句或是表结构的性能瓶颈。 MySQL查询过程 通过explain我们可以获得以下信息: 表的读取顺序 数据读取操作的操作类型 哪些索引可以被使用 …...
Kafka3.0.0版本——增加副本因子
目录 一、服务器信息二、启动zookeeper和kafka集群2.1、先启动zookeeper集群2.2、再启动kafka集群 三、增加副本因子3.1、增加副本因子的概述3.2、增加副本因子的示例3.2.1、创建topic(主题)3.2.2、手动增加副本存储 一、服务器信息 四台服务器 原始服务器名称原始服务器ip节点…...
升级iOS 17出现白苹果、不断重启等系统问题怎么办?
iOS 17发布后了,很多果粉都迫不及待的将iphone/ipad升级到最新iOS17系统,体验新系统功能。 但部分果粉因硬件、软件的各种情况,导致升级系统后出现故障,比如白苹果、不断重启、卡在系统升级界面等等问题。 如果遇到了这些系统问题…...
6. `Java` 并发基础之`ReentrantReadLock`
前言:随着多线程程序的普及,线程同步的问题变得越来越常见。Java中提供了多种同步机制来确保线程安全,其中之一就是ReentrantLock。ReentrantLock是Java中比较常用的一种同步机制,它提供了一系列比synchronized更加灵活和可控的操…...
float浮动布局大战position定位布局
华子目录 布局方式普通文档流布局浮动布局(浮动主要针对与black,inline元素)float属性浮动用途浮动元素父级高度塌陷 position属性定位篇相对定位(relative为属性值,配合left属性,和top属性使用)…...
算法 数据结构 递归插入排序 java插入排序 递归求解插入排序算法 如何用递归写插入排序 插入排序动图 插入排序优化 数据结构(十)
1. 插入排序(insertion-sort): 是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入 算法稳定性: 对于两个相同的数,经过…...
OpenCV(二十二):均值滤波、方框滤波和高斯滤波
目录 1.均值滤波 2.方框滤波 3.高斯滤波 1.均值滤波 OpenCV中的均值滤波(Mean Filter)是一种简单的滤波技术,用于平滑图像并减少噪声。它的原理非常简单:对于每个像素,将其与其周围邻域内像素的平均值作为新的像素值…...
二叉树的递归遍历和非递归遍历
目录 一.二叉树的递归遍历 1.先序遍历二叉树 2.中序遍历二叉树 3.后序遍历二叉树 二.非递归遍历(栈) 1.先序遍历 2.中序遍历 3.后序遍历 一.二叉树的递归遍历 定义二叉树 #其中TElemType可以是int或者是char,根据要求自定 typedef struct BiNode{TElemType data;stru…...
JDK17:未来已来,你准备好了吗?
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…...
K8s和Docker
Kubernetes(简称为K8s)和Docker是两个相关但又不同的技术。 一、Docker 1、Docker是一种容器化平台,用于将应用程序及其依赖项打包成可移植的容器。 2、Docker容器可以在任何支持Docker的操作系统上运行 好处:提供了一种轻量级…...
使用物理机服务器应该注意的事项
使用物理机服务器应该注意的事项 如今云计算的发展已经遍布各大领域,尽管现在的云服务器火遍全网,但是仍有一些大型企业依旧选择使用独立物理服务器,你知道这是为什么吗?壹基比小鑫来告诉你吧。 独立物理服务器托管业务适合大中…...
py脚本解决ArcGIS Server服务内存过大的问题
在一台服务器上,使用ArcGIS Server发布地图服务,但是地图服务较多,在发布之后,服务器的内存持续处在95%上下的高位状态,导致服务器运行状态不稳定,经常需要重新启动。重新启动后重新进入这种内存高位的陷阱…...
Go语言Web开发入门指南
Go语言Web开发入门指南 欢迎来到Go语言的Web开发入门指南。Go语言因其出色的性能和并发支持而成为Web开发的热门选择。在本篇文章中,我们将介绍如何使用Go语言构建简单的Web应用程序,包括路由、模板、数据库连接和静态文件服务。 准备工作 在开始之前…...
保姆级教程——VSCode如何在Mac上配置C++的运行环境
vscode官方下载: 点击官网链接,下载对应的pkg,安装打开; https://code.visualstudio.com/插件安装 点击箭头所指插件商店按钮,yyds; 下载C/C 插件; ![外链图片转存 下载CodeLLDB插件&#x…...
Java 操作FTP服务器进行下载文件
用Java去操作FTP服务器去做下载,本文章里面分为单个下载和批量下载,批量下载只不过多了一层循环,为了方便参考,我代码都贴出来了。 不管单个下载还是多个,一定要记得,远程服务器的直接写文件夹路径…...
物理机服务器应该注意的事
物理机服务器应该注意的事 1、选址 服务器是个非常重要的硬件产品,对机房的也是有一定的要求的,比如温度、安全性,噪音、电源稳定性等等问题都需要解决!但是不是每个人都会选择自己建立一个机房,毕竟各方面加起来的成本都太高。这…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...

