【MySQL — 数据库基础】深入解析 MySQL 的联合查询

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


1. 插入查询结果


语法


insert into table_name1 select* from table_name2 where restrictions ;

注意:查询的结果集合,列数 / 类型 / 顺序 要和 insert into 后面的表相匹配;列的名字不要求相同;


create table student1(id int , name varchar(20));create table student2(id int , name varchar(20));

要点讲解


1. 查询的结果集合,列数 / 类型 / 顺序要和 insert into 后面的表相匹配

insert into student1 values(1, '张三'), (2, '李四'), (100, '赵六');insert into student2 select* from student1 where id < 50;  -- 插入查询结果

在这里插入图片描述


2. 插入查询的表的列名,与插入的表列名不要求相同

drop table student2;create table student2(StudentId int , StudentName varchar(20));  -- 新创建的 student2 的列名和 student1 不同insert into student2 select* from student1 where id < 50;

在这里插入图片描述


3. 查询的结果集合,列数 / 类型 / 顺序和 insert into 后面的表不匹配,会报错
drop table student2;create table student2( StudentName varchar(20), StudentId int); -- 类型和 student1 不匹配insert into student2 select* from student1 where id < 50; 

在这里插入图片描述


4. 两个表的列类型不匹配,可以指定插入顺序,也可以指定查询顺序
insert into student2(StudentId, StudentName) select* from student1;  -- 指定插入顺序insert into student2 select name , id from student1;                 -- 指定查询顺序

2. 笛卡尔积


概念


笛卡尔积就像是把两个集合中的每一项都“配对”起来。

比如你有两个表,一个是人员名单,一个是产品清单

  • 人员名单:Alice 和 Bob
  • 产品清单:Apple 和 Banana

如果你把每个人和每个产品都配对一次,就得到以下组合:

  • Alice 和 Apple
  • Alice 和 Banana
  • Bob 和 Apple
  • Bob 和 Banana

这就是笛卡尔积的结果。


简单来说,就是把一个表的每一行和另一个表的每一行都组合一下: 笛卡尔积的列数,就是刚才两个表的列数之和; 笛卡尔积的行数,就是两张表行数的乘积。

所谓的 “多表联合查询”,是基于笛卡尔积这样的运算展开的;但注意,笛卡尔积很容易产生大量不需要的数据,所以一般要避免在查询中直接用它,除非有特别的需要。


在这里插入图片描述


通过SQL计算笛卡尔积


create table class(classId int, className varchar(20)); insert into class values
(1, '一班'), 
(2, '2班');create table student(id int , name varchar(20) , classId int );insert into student values
(1, '张三', 1) , 
(2, '李四', 1) , 
(3, '王五', 2) , 
(4, '赵六', 2) ;select* from student, class;  -- 通过 SQL 计算笛卡尔积,将两张表综合在一起进行查询

在这里插入图片描述


要想进行一些更有实际意义的查询,就需要指定一些额外的条件:


在笛卡尔积查询 student 和 class 时,我们期望进行笛卡尔积的记录是 classId 相同的记录
select* from student , class  where classId = classId ;  

在这里插入图片描述


为了解决" classId 是哪张表的 classId " 这个歧义,我们需要显式指定 classId 是属于哪张表的
select* from student , class  where student.classId = class.classId ; -- 使用成员访问运算符. 来指定 classId 是属于哪张表的

在这里插入图片描述


3. 一次完整的联合查询过程


构造数据

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) , class_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
('计算机系2019级1班', '学习了计算机原理、C和Java语言、数据结构和算法'),
('中文系2019级3班', '学习了中国传统文学'),
('自动化2019级5班', '学习了机械自动化');-- 插入学生信息
insert into student (sn, name, qq_mail, class_id) VALUES
('09982', '黑旋风李逵', 'xuanfengaqq.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);-- 插入课程信息
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),
-- tellme
(80, 7, 2), (92, 7, 6);

测试数据主要包含三个实体:学生,班级,课程;

学生 - 班级 属于一对多的关系,学生 - 课程 属于多对多的关系,所以我们需要通过一个关联表 score ,来体现课程和学生两个实体的联系;


内连接


语法


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

在这里插入图片描述


案例


查询“许仙”同学的成绩

在这里插入图片描述


初学多表查询阶段,不建议一次写出最终的SQL语句,可以一步步的优化查询,根据规律写出最终SQL;


在这里插入图片描述


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

在这里插入图片描述

select student.id , student.name , sum(score.score) 
from student, score 
where student.id = score.student_id 
group by student.id ;

在这里插入图片描述


查询所有同学的总成绩, 列出同学姓名,课程名字,课程分数....

在这里插入图片描述

select student.name as studentName , course.name as courseName , score.score 
from student , course , score 
where student.id = score.student_id and course.id = score.course_id ;

在这里插入图片描述


使用 join on 的方式查询,可以更好的体现出表两两之间的联合查询过程

select* from student 	
join score 
on student.id = score.student_id 
join course 
on score.course_id = course.id ;

在这里插入图片描述

select student.name as studentName , course.name as courseName , score .score 
from student 
join score on student.id = score.student_id 
join course on course.id = score.course_id ;  -- 精简查询

在这里插入图片描述


外连接


语法


外连接也是 join on 这样的写法,但是不支持 from 多个表 ;

外连接分为左外连接和右外连接;

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

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

案例


create table student( id int , name varchar(20) ) ;create table score( id int , score int ) ;insert into student values( 1 , '张三' ), ( 2 , '李四' ), ( 3 , '王五' );insert into score values(1 , 90) , (2 , 80) , (3 , 70) ;

创建的这张表的数据是一一对应的,进行内连接和外连接,得到的结果完全相同;

但是如果上述的数据不再一一对应,内连接的结果和外连接就会出现差别;

update score set id = 4 where score = 70 ;-- 修改数据

内连接
select name , score from student  ,   score where student.id = score.id;-- 这个写法只能表示内连接,不能表示外连接select name , score from student join score  on   student.id = score.id;select name , score from student inner join score  on   student.id = score.id;-- inner join 表示内连接,inner 关键字可以省略-- 内连接,查询结果只会包含两个表中同时具备的数据

在这里插入图片描述


外连接
select name , score from student left join score on student.id = score.id ;-- 左外连接select name , score from student right join score on student.id = score.id ;-- 右外连接

在这里插入图片描述


自连接


自连接是指在同一张表连接自身进行查询,这并不是常规操作,而是针对特殊的情况的处理;


案例


查询计算机组成原理分数高于 Java 的同学

在这里插入图片描述


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


如果发现要查询的条件是针对两行,而不是两列,就可以考虑使用自连接进行转换; 自连接前要先清楚表的量级,如何表非常大,连接开销也会非常庞大,容易就把数据库搞死了.


子查询


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


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

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

在这里插入图片描述


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

使用多行子查询,就不能使用= > <这样的运算符直接比较了,但是可以使用 in


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

在这里插入图片描述


合并查询


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

使用 UNION 和 UNION ALL 时,前后查询的结果集中,字段需要一致(要求合并双方的类型,个数,顺序要相同,列名不要求相同)。


union


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


案例:查询id小于3,或者名字为“英文”的课程:select* from course where id < 3 union select* from course where name ='英文' ;-- 将两条SQL语句的查询结果一次性合在一张表中select* from course where id < 3 or name = '英文' ;-- 针对同一张表的查询, union 和 or 的效果相同,但是如果是不同的表,就只能用 union,不能用 or

在这里插入图片描述


union all


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

-- 查询id小于3,或者名字为“Java”的课程select* from course where id < 3 union all select* from course where name = 'Java' ;

在这里插入图片描述


SQL查询中各个关键字的执行先后顺序


from > on> join > where > group by > with > having > select > distinct > order by > limit


在这里插入图片描述


在这里插入图片描述

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

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

相关文章

spring cloud 使用 webSocket

1.引入依赖,(在微服务模块中) <!-- Spring WebSocket --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency> 2.新建文件 package com.ruoyi.founda…

《aarch64汇编从入门到精通》-204页PPT+实验

&#x1f534;【课程特色】 ✅1、依照官方文档总结制作&#xff0c;体系更完整&#xff0c;不遗漏知识&#xff1b; ✅2、基于Armv8/Armv9架构讲解汇编。真正的ARM汇编&#xff1b; ✅3、资料更全。200多页PPT资料&#xff0c;其它参考资料; ✅4、学完ARM架构&#xff0c;再学汇…

企业使用统一终端管理(UEM)工具提高端点安全性

什么是统一终端管理(UEM) 统一终端管理(UEM)是一种从单个控制台管理和保护企业中所有端点的方法&#xff0c;包括智能手机、平板电脑、笔记本电脑、台式机和 IoT设备。UEM 解决方案为 IT 管理员提供了一个集中式平台&#xff0c;用于跨所有作系统和设备类型部署、配置、管理和…

20250213 隨筆 雪花算法

雪花算法&#xff08;Snowflake Algorithm&#xff09; 雪花算法&#xff08;Snowflake&#xff09; 是 Twitter 在 2010 年開發的一種 分布式唯一 ID 生成算法&#xff0c;它可以在 高併發場景下快速生成全局唯一的 64-bit 長整型 ID&#xff0c;且不依賴資料庫&#xff0c;具…

QT 异步编程之多线程

一、概述 1、在进行桌面应用程序开发的时候&#xff0c;假设应用程序在某些情况下需要处理比较复制的逻辑&#xff0c;如果只有一个线程去处理&#xff0c;就会导致窗口卡顿&#xff0c;无法处理用户的相关操作。这种情况下就需要使用多线程&#xff0c;其中一个线程处理窗口事…

leetcode 543. 二叉树的直径

题目如下 数据范围 示例 显然直径等于左右子树高之和的最大值。通过代码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* Tr…

IP 路由基础 | 路由条目生成 / 路由表内信息获取

注&#xff1a;本文为 “IP 路由” 相关文章合辑。 未整理去重。 IP 路由基础 秦同学学学已于 2022-04-09 18:44:20 修改 一. IP 路由产生背景 我们都知道 IP 地址可以标识网络中的一个节点&#xff0c;并且每个 IP 地址都有自己的网段&#xff0c;各个网段并不相同&#xf…

sql:时间盲注和boolen盲注

关于时间盲注&#xff0c;boolen盲注的后面几个获取表、列、具体数据的函数补全 时间盲注方法 import time import requests# 获取数据库名 def inject_database(url):dataname for i in range(1, 20):low 32high 128mid (low high) // 2while low < high:payload &q…

zyNo.22

常见Web漏洞解析 命令执行漏洞 1.Bash与CMD常用命令 &#xff08;1&#xff09;Bash 读取文件&#xff1a;最常见的命令cat flag 在 Bash 中&#xff0c;cat 以及的tac、nl、more、head、less、tail、od、pr 均为文件读取相关命令&#xff0c;它们的区别如下&#xff1a; …

《Python 中 JSON 的魔法秘籍:从入门到精通的进阶指南》

在当今数字化时代&#xff0c;网络编程无处不在&#xff0c;数据的高效传输与交互是其核心。JSON 作为一种轻量级的数据交换格式&#xff0c;凭借其简洁、易读、跨语言的特性&#xff0c;成为网络编程中数据传输与存储的关键技术。无论是前后端数据交互&#xff0c;还是不同系统…

部门管理(体验,最原始方法来做,Django+mysql)

本人初学&#xff0c;写完代码在此记录和复盘 在创建和注册完APP之后&#xff08;我的命名是employees&#xff09;&#xff0c;编写models.py文件创建表 手动插入了几条数据 1.部门查询 urls.py和views.py在编写之前&#xff0c;都要注意导入对应的库 urls.py&#xff1a;…

Docker的容器

Docker的容器 一&#xff0e;容器 容器是一种轻量级的虚拟化技术。它有效的将单个操作系统的资源划分到各独立的组中&#xff0c;以便更好的平衡这些独立的组之间资源的使用。 容器主要包含了命名空间&#xff08;Namespaces&#xff09;和cgroup&#xff08;Control Groups…

[Redis] Redis分布式锁与常见面试题

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

Word 公式转 CSDN 插件 发布

经过几个月的苦修&#xff0c;这款插件终于面世了。 从Word复制公式到CSDN粘贴&#xff0c;总是出现公式中的文字被单独提出来&#xff0c;而公式作为一个图片被粘贴的情况。公式多了的时候还会导致CSDN禁止进一步的上传公式。 经过对CSDN公式的研究&#xff0c;发现在粘贴公…

JVM——堆的回收:引用计数发和可达性分析法、五种对象引用

目录 引用计数法和可达性分析法 引用计数法&#xff1a; 可达性分析算法&#xff1a; 五种对象引用 软引用&#xff1a; 弱引用&#xff1a; 引用计数法和可达性分析法 引用计数法&#xff1a; 引用计数法会为每个对象维护一个引用计数器&#xff0c;当对象被引用时加1&…

sqlilabs--小实验

一、先盲注判断 ?id1 and sleep(2)-- 如果发现页面存在注点&#xff0c;使用时间盲注脚本进行注入 import requestsdef inject_database(url):name for i in range(1, 20): # 假设数据库名称长度不超过20low 48 # 0high 122 # zmiddle (low high) // 2while low &l…

VMware Workstate 的 Ubuntu18 安装 vmware tools(不安装没法共享)

在共享主机路径后&#xff0c;可以在&#xff1a; /mnt/hgfs/下方找到共享的文件。但没有安装vmware tool时是没法共享的。 如何安装vmware tool&#xff0c;网上版本很多。这里记录一下&#xff1a; VMware Workstation 17 Pro&#xff0c;版本&#xff1a;17.6.0 虚拟机系统…

STM32 I2C通信协议说明

目录 背景 I2C协议 数据的有效性 I2C通信开始和停止条件 I2C数据传输 发送 响应 正常情况&#xff1a; 异常情况&#xff1a; 主机结束接收 写寄存器的标准流程 读寄存器的标准流程 仲裁机制 时钟同步 SDA线的仲裁 程序 背景 对单片机的三大通信中的I2C通信进…

Unity与SVN集成:实现高效版本控制

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity与SVN集成&#xff1a;实现高效版本控制 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取&…

BUU37 [DASCTF X GFCTF 2024|四月开启第一局]web1234【代码审计/序列化/RCE】

Hint1&#xff1a;本题的 flag 不在环境变量中 Hint2&#xff1a;session_start&#xff08;&#xff09;&#xff0c;注意链子挖掘 题目&#xff1a; 扫描出来www.zip class.php <?phpclass Admin{public $Config;public function __construct($Config){//安全获取基…