MySQL表的增删查改(3)——复杂情况

news2024/12/28 2:02:50

1. 表的设计

三大范式:

一对一:如一个学生可以有一个学号,一个学号只能被一个学生拥有

一对多:如一个学生只能属于一个班级,但一个班级可以有多个学生(这种方案在MySQL中是不可行的,但在有些数据库(如Redis中)能够支持列表,如下图:

多对多:如一个学生可以选择多门课程,一个课程可以被多个学生选择

2. 新增

插入查询结果(即将表1的查询结果插入到表2中,表1得到的结果集合(列数、类型、顺序)要和insert into后面的表2相匹配,列的名字不要求相同)

语法:

INSERT INTO table_name [(column [, column ...])] SELECT ...

示例:

--只有表名不同的两个表,将表1中数据根据筛选条件新增到表2中
create table student(id int, name varchar(20));
create table student2(id int, name varchar(20));
insert into student values (1,'zhangsan'),(2,'lisi'),(3,'wangwu'),(100,'zhaoliu');
insert into student2 select * from student where id < 50;


--表明不同,列名不同的情况,也可以成功新增
create table student(id int, name varchar(20));
create table student2(classId int, className varchar(20));


--表名不同,列名类型相同,但顺序不同
create table student(id int, name varchar(20));
create table student2(name varchar(20), id int);
insert into student2(id, name) select * from student; --两种方法均可
insert into student2 select name, id from student;

3. 查询

3.1 聚合查询

3.1.1 聚合函数

常见的统计总数、计算平均值等操作可以使用聚合函数来实现,常见的聚合函数:

函数说明
COUNT([DISTINCT] expr)返回查询到的数据的 数量
SUM([DISTINCT] expr)返回查询到的数据的 总和,不是数字没有意义
AVG([DISTINCT] expr)返回查询到的数据的 平均值,不是数字没有意义
MAX([DISTINCT] expr)返回查询到的数据的 最大值,不是数字没有意义
MIN([DISTINCT] expr)返回查询到的数据的 最小值,不是数字没有意义

示例:

count
--统计班级里共有多少同学
select count(*) from student;
select count(0) from student;

--统计班级收集到的qq_mail有多少个,为NULL的数据不会计入结果
select count(qq_mail) from student;


 sum
--统计数学成绩总分
select sum(math) from exam_result;

--不及格(<60)同学的总分,没有结果返回null
select sum(math) from exam_result where math < 60;

tip:需要确保进行求和的列是数字,如果是字符串就会出现问题

虽然能将是数字的字符串转换出来,但是原则上不应该对字符串进行求和操作,如:字符串类型的手机号/身份证号...这些转换成数字进行求和操作是无意义的


avg
--计算平均总分
select avg(chinese + math + english) 平均总分 from exam_result;
max
--返回英语最高分
select max(english) from exam_result;
min
--返回 >70 分以上的数学最低分
select min(math) from exam_result where math > 70;

3.1.2 group by 子句

使用 group by 指定一个列,就会把 列的值 相同的 行 归到一组中,分完组之后,还可以针对每个组分别进行聚合查询

语法:
select column1, sum(column2), .. from table group by column1,column3;
示例:
mysql> select * from emp;
+------+--------+-----------+--------+
| id   | name   | role      | salary |
+------+--------+-----------+--------+
|    1 | 张三   | 程序员    |  10000 |
|    2 | 李四   | 程序员    |  11000 |
|    3 | 王五   | 程序员    |  12000 |
|    4 | 赵六   | 产品      |   8000 |
|    5 | 田七   | 产品      |   9000 |
|    6 | 周八   | 老板      | 100000 |
+------+--------+-----------+--------+
6 rows in set (0.00 sec)


搭配条件使用的情况:

1)分组之前的条件:查询每个岗位的平均薪资,除去张三这个人

2)分组之后的条件:查询每个岗位的平均薪资,排除平均薪资超过5w的记录

3)一个查询同时包含分组前条件和分组后条件:查询每个岗位的平均薪资,排除张三,也排除平均薪资超过5w的结果

3.1.3 having

group by 子句进行分组以后,需要对分组结果再进行条件过滤时,不能使用where语句,而需要用having,例如上面例2)和例3)。

3.2 联合查询

实际开发中往往数据来自不同的表,所以需要多表联合查询

多表查询是对多张表的数据取笛卡尔积:

tip:关联查询可以对关联表使用别名

 进行多表查询时,通常会通过一定的条件把笛卡尔积中的“合法数据”筛选出来,这样的条件就称为“连接条件”。

示例:初始化测试数据

-- 删除重复表
drop table if exists classes;
drop table if exists student;
drop table if exists course;
drop table if exists score;

-- 创建学生相关表
create table classes (id int primary key auto_increment, name varchar(20), `desc` varchar(100));

create table student (id int primary key auto_increment, sn varchar(20), name varchar(20), qq_mail varchar(20), classes_id int);

create table course (id int primary key auto_increment, name varchar(20));

create table score (score decimal(3,1), student_id int, course_id int);

-- 对各表插入相应数据
insert into classes(name, `desc`) values 
('计算机系2024级1班', '学习了计算机原理、C和Java语言、数据结构和算法'),
('中文系2024级3班','学习了中国传统文学'),
('自动化2024级5班','学习了机械自动化');


insert into student(sn, name, qq_mail, classes_id) values 
('09982','刘一','liuyi@qq.com',1), 
('00835','陈二',null,1), 
('00391','张三',null,1), 
('00031','李四','lisi@qq.com',1), 
('00054','王五',null,1), 
('51234','赵六','zhaoliu@qq.com',2), 
('83223','孙七',null,2), 
('09527','周八','zhouba@qq.com',2);

insert into course(name) values ('Java'), ('中国传统文化'),('计算机原理'),('语文'),('高等数学'),('英语');


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),
-- 赵六
(56, 6, 2),(43, 6, 4),(79, 6, 6),
-- 孙七
(80, 7, 2),(92, 7, 6);

3.2.1 内连接

语法:

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

示例:

(1) 查询“李四”同学的成绩

查询步骤:

a) 分析问题,了解清楚要查询内容在哪些表中存在(该流程使用 , where 的方式演示)

此处查询内容在 学生表 和 分数表 中

b) 对这两个表进行笛卡尔积

c) 指定连接条件,筛选掉无效数据

d) 根据需要进一步指定条件,对数据再筛选(新加的条件往往通过 and 的方式 和 连接条件放在一起)

 e) 针对查询中的列进行精简


多表查询的另一个写法 join on

a) 分析问题,了解清楚要查询内容在哪些表中存在

b) 对这两个表进行笛卡尔积

c) 指定连接条件,筛选掉无效数据(通过 on 关键字)

d) 根据需要进一步指定条件,对数据再筛选

e) 针对查询中的列进行精简

相比于直接多个表 , where 的方式来说,join on 的方式支持的功能更多一些,在实际开发中,两种写法都需掌握

(2)查询所有同学的成绩,及同学的个人信息(每个同学都有多门课程,把多门课程的分数加在一起)

tip:此处分数不是按照 来表示的,而是按照 !同时还需要搭配 分组 操作把每个同学的成绩相加

a) 分析问题,了解清楚要查询内容在哪些表中存在(学生表、分数表)

b) 对这两个表进行笛卡尔积

c) 指定连接条件,筛选掉无效数据

d) 针对上述数据进行 分组聚合


使用  join on 的方式:

(3)查询所有同学的成绩,及同学的个人信息(列出同学姓名、课程名字、课程分数)

tip:查出来的都是有成绩的同学,“周八”同学没有显示

a) 分析问题,了解清楚要查询内容在哪些表中存在

需针对 student、course、score 三个表计算笛卡尔积

b) 对这三个表进行笛卡尔积

c) 指定连接条件,筛选掉无效数据

e) 针对查询中的列进行精简


也可使用 join on 的方式来写,更能清楚的体现出联合查询的过程:

tip:虽然可以拿任意个表进行笛卡尔积操作,但是由于笛卡尔积可能会产生大量的“中间结果”,就会对性能影响很大,甚至严重的可能会将数据库搞挂,因此,多表联合查询 使用时要慎重,需要先对当前这样的多表查询大概会涉及到多少数据量操作,有一个“预估”。

3.2.2 外连接

外连接分为左外连接和右外连接,如果联合查询,左侧的表完全显示就认为是左外连接;右侧的表完全显示就认为是右外连接

语法:

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

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

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

示例数据:

, where 只能表示内连接,不能表示外连接

内连接查询结果,只包含两个表中同时具备的数据

join 前面加上 inner 就是内连接,平常可以省略不写


外连接就是给 join 前面加上 left / right 表示外连接(不支持 from 多个表)

左外连接:

左连接就是以左表为基准,能够确保左表中的每个记录都出现在最终结果中,如果左表中的记录在右表中没有对应的记录,此时就会把右表中的相关字段填为 NULL

右外连接

原理同上 左连接

全外连接:(MySQL不支持全外连接)

3.2.3 自连接

自连接是指在同一张表连接自身进行查询

示例:显示所有“计算机原理”成绩比“Java”成绩高的成绩信息

通过上面两个表,可以发现学号为 1 和学号为 3 的同学满足条件

而 sql 中进行的条件查询是针对两个 进行比较的,不能比较两个

自连接本质上就能把 行关系 转换成 列关系(典型的数学思维:将未知问题转成已知问题)

将成绩表直接笛卡尔积:

错误信息:表的别名不唯一

这里需要给这个表前后分别起不同的别名,再进行连接

此时需要指定连接条件,筛选掉无效数据(此处连接条件不能选则课程id,因为课程id是问题条件,也不能选成绩,若碰巧遇到相同的成绩就会有误差,只能选学生id作为连接条件)

 

 进一步条件筛选

上面结果说明,score表中,只有三个同学同时具有 计算机原理 和 Java 课程成绩

再进一步筛选,发现当前要查询的条件是针对 两行,而不是 两列,就可以考虑使用自连接进行转换

 自连接的时候,表非常大,连接的开销也会非常庞大,容易把数据库搞挂!

3.2.3 子查询

子查询是指嵌入在其他 sql 语句中的 select 语句,也叫嵌套查询

简单理解就是套娃,本来就一个需求,需要通过多个 sql 来完成,但现在偏要把多个 sql 合并成一个,这种做法是和软件开发的基本原则(化繁为简)背道而驰的,所以不推荐使用

单行子查询:返回一行记录的子查询

查询“王五”同学的同班同学

可以通过以下两步完成该任务

使用自连接的方式

 

很明显,这样的代码看起来更加复杂,可读性很差


多行子查询:返回多行记录的子查询

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

1. [NOT]IN 关键字

此时不能使用 = > < 这样的运算符直接比较了

可以使用in

2. [NOT]EXISTS 关键字

exists 非常消耗时间,背后会触发大量的硬盘 IO 操作,更不推荐使用!


3.2.5 合并查询

在实际应用中,为了合并多个 select 的执行结果,可以使用结合操作符 union、union all

使用 union 和 union all 时,前后查询的结果集中,字段需要一致

1. union

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

示例:查询 id 小于 3,或者名字为“英语”的课程

2. union all

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

示例:查询 id 小于 3,或者名字为 “Java” 的课程

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

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

相关文章

深入浅出mediasoup—关键帧请求

当丢包或者解码错误导致无法正确解码视频流&#xff0c;或者当一个新的接收者加入到视频通话时&#xff0c;需要一个关键帧来恢复和开始正常解码。关键帧请求机制是确保视频流在不可靠网络环境下能够恢复和维持高质量播放的关键技术之一&#xff0c;mediasoup 支持关键帧请求。…

一文掌握YOLOv1-v10

引言 YOLO目标检测算法&#xff0c;不过多介绍&#xff0c;是基于深度学习的目标检测算法中最出名、发展最好的检测器&#xff0c;没有之一。本文简要的介绍一下从YOLOv1-YOLOv10的演化过程&#xff0c;详细技术细节不过多介绍&#xff0c;只提及改进点&#xff0c;适合初学者…

每日OJ_牛客_HJ91 走方格的方案数

目录 牛客HJ91 走方格的方案数 解析代码 牛客HJ91 走方格的方案数 走方格的方案数_牛客题霸_牛客网 解析代码 本题为求取路径总数的题目&#xff0c;一般可以通过递归求解&#xff0c;对于复杂的问题&#xff0c;可以通过动态规划求解。此题比较简单&#xff0c;也可以通过递…

AI学习记录 - transformer的位置编码的理解

看完肯定懂&#xff0c;可能会更新 一看位置编码公式&#xff0c;感觉很懵逼 懵逼四点&#xff1a;&#xff08;或者你还有其他不懂的点&#xff09; 1、为什么使用正弦余弦公式&#xff1f;不可以使用其他公式&#xff1f; 2、为什么奇数位置使用余弦&#xff0c;偶数位置使…

向量数据库:从0到original paper

向量数据库相关概念 亿点点历史知识 LLM的模型发展历史&#xff0c;Harnessing the Power of LLMs in Practice: A Survey on ChatGPT and Beyond1&#xff1a; 很多人都是从ChatGPT爆点后才逐渐了解到大模型&#xff0c;但在爆点的前几年大模型的发展已经开始了诸神之战。一…

网络服务综合项目(一键部署shell脚本)

目录 需求&#xff1a; 主机环境描述 注意&#xff1a; 项目需求&#xff1a; 代码讲解 配置本地仓库 安装软件包 配置防火墙 配置策略中的一个布尔值 配置web服务 配置网络仓库 配置DNS服务 配置NTP服务 配置MySQL服务 配置NFS服务 配置论坛服务 进入网站配置…

数据结构(稀疏数组)

简介 稀疏数组是一种数据结构&#xff0c;用于有效地存储和处理那些大多数元素都是零或者重复值的数组。在稀疏数组中&#xff0c;只有非零或非重复的元素会被存储&#xff0c;从而节省内存空间。 案例引入 假如想把下面这张表存入文件&#xff0c;我们会怎么做&#xff1f;…

C语言字符函数与字符串函数超详解

文章目录 前言1. 字符分类函数2. 字符转换函数3. strlen3. 1 strlen 的使用3. 2 strlen 的模拟实现 4. strcpy4. 1 strcpy 的使用4. 2 strcpy 的模拟实现 5. strcat5. 1 strcat 的使用5. 2 strcat 的模拟实现 6. strcmp6. 1 strcmp 的使用6. 2 strcmp 的模拟实现 7. strncpy 函…

如何获得某个Window画面所属包名packageName和用户userId

在安卓上获得某个Window画面所属包名packageName和用户userId的方法 1&#xff0c;用到的工具如下&#xff1a; adb androidSDK里的monitor工具 adb shell dumpsys window animator adb shell dumpsys window命令 jdk 1.8已在安卓14模拟器上测试通过。 以AOSP的launcher中的m…

Nacos适配达梦数据库并制作镜像

背景&#xff1a;因项目需要信创&#xff0c;需将原本的mysql数据库&#xff0c;改成达梦数据库 一、部署达梦数据库 1.1 部署达梦数据库服务 可参考&#xff1a;Docker安装达梦数据库_达梦数据库docker镜像-CSDN博客 1.2 创建nacos数据库 create user SAFE_NACOS identifi…

pythonGame-实现简单的贪食蛇游戏

通过python简单复现贪食蛇游戏。 使用到的库函数&#xff1a; import pygame import time import random 游戏源码&#xff1a; import pygame import time import randompygame.init()white (255, 255, 255) yellow (255, 255, 102) black (0, 0, 0) red (213, 50, 80…

【秋招突围】2024届秋招笔试-美团笔试题-第一套-三语言题解(Java/Cpp/Python)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新 美团 春秋招笔试题**汇总~ 👏 感谢大家的订阅➕ 和 喜欢💗 01.LYA 的音乐播放列表 问题描述 LYA 有一个包含 n n n 首歌曲的音乐播放列表,歌曲编号从 1 1

护网紧急情况应对指南:Linux 应急响应手册

继上一篇&#xff1a;护网紧急情况应对指南&#xff1a;Windows版v1.2全新升级版 之后 收到小伙伴后台要Linux应急手册&#xff0c;今天给大家安排上。 《Linux应急手册》是一本为Linux系统管理员和运维工程师量身打造的实用指南&#xff0c;旨在帮助他们快速应对各种突发状况…

电测量数据交换DLMSCOSEM组件第10部分:智能测量标准化框架

1.GB/T 17215.6XY系列 IEC 62056 DLMS/COSEM组件标准已经由IEC/TC 13完成制定,用于电测量的目的。有些标准——特别是COSEM数据模型——也已经被其他非电量测量的技术委员会使用。IEC62056-X-Y系列标准对应转换国标GB/T 17215.6XY系列(电测量数据交换DLMSCOSEM组件)。如下图…

Electron的入门介绍与使用(1)共30节

Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows上运行的跨平台应用 macOS和Linux——不需要本地开发 经验。 入门指南​ Electron 是网页应用 …

repo 工具安装和使用教程(windows+gitee)

repo是什么 官方的定义&#xff1a;Repo是谷歌用python脚本写的调用git的一个脚本&#xff0c;可以实现管理多个git库。 Android的源代码使用Repo 命令行工具来管理多个git仓库&#xff0c;大概有百多个。要想克隆和管理百多个 Git 仓库&#xff0c;不是一件简单的事情。Repo 命…

Java集合——HashMap的底层实现

HashMap将数据以键值对的形式存储&#xff0c;是线程不安全的&#xff08;即在多线程中若不用concurrentHashMap会导致结果错误&#xff09;。 // concurrentHashMap编程示例 import java.util.Map; import java.util.concurrent.ConcurrentHashMap;public class HashMapThrea…

快手电商Android一面凉经(2024)

快手电商Android一面凉经(2024) 笔者作为一名双非二本毕业7年老Android, 最近面试了不少公司, 目前已告一段落, 整理一下各家的面试问题, 打算陆续发布出来, 供有缘人参考。今天给大家带来的是《快手电商Android一面凉经(2024)》。 面试职位: Android工程师 技术一面 面试形式…

新手小白的pytorch学习第十四弹------十一、十二、十三弹卷积神经网络CNN的习题

习题编号目录 No 1No 2No 3No 4No 5No 6No 7No 8No 9No 10No 11No 12No 13 练习题主要就是 写代码&#xff0c;所以这篇文章大部分是代码哟~ No 1 What are 3 areas in industry where computer vision is currently being used? No 2 工业异常检测&#xff0c;目标检测 Sea…

C语言 -- sizeof和strlen的用法

C语言 -- sizeof和strlen的用法 1. sizeof和strlen的对比​1.1 sizeof​1.2 strlen​1.3 sizeof 和 strlen的对比​ 2. 数组和指针笔试题解析2.1 一维数组​2.2 字符数组​2.3 二维数组 3. 指针运算笔试题解析3.1 题目1&#xff1a;3.2 题目2​3.3 题目3​3.4 题目4​3.5 题目5…