首页/新闻资讯/正文详情

MySQL数据库:联合查询

发布时间:2026/9/27 11:18:30 来源:云帆数科 栏目:资讯中心
MySQL数据库:联合查询
适用环境MySQL 8.0示例按 MySQL 8.0.39 编写1. 联合查询解决什么问题规范化会把实体拆到不同表中读取完整业务信息时需要重新组合数据“联合查询”在本章中是一个宽泛概念主要包括类型解决的问题常用语法表连接横向组合有关联的表增加列join、left join子查询把一个查询的结果交给另一个查询使用in、exists、标量子查询集合查询纵向合并多个结构相同的结果集增加行union、union all查询结果写入把查询出的行保存到表中insert ... select、create table ... select外键不会自动连接表查询仍须写连接条件2. 多表查询的逻辑与实际执行2.1 用笛卡尔积理解逻辑结果若 A 表有 3 行、B 表有 4 行交叉连接会产生3 × 4 12行select*fromtable_acrossjointable_b;内连接可在逻辑上理解为“组合后保留满足条件的行”selects.name,c.class_namefromstudent_design2 sjoinclass_design2 conc.ids.class_id;漏写条件会使行数成倍膨胀一对多连接还会按匹配数重复左侧行2.2 MySQL 不一定真的生成完整笛卡尔积笛卡尔积是逻辑模型不等于物理执行。优化器会根据统计信息、索引和成本决定表的连接顺序而不一定按 SQL 中的书写顺序为每张表选择全表扫描、索引范围扫描或索引查找选择嵌套循环连接或 Hash Join 等算法尽早过滤无效行MySQL 常用嵌套循环合适的连接索引可加快内层查找。8.0.18 起支持 Hash Join8.0.20 起用它替代 Block Nested-Loop 的场景SQL 的逻辑处理顺序可简化为3. 内连接 INNER JOIN3.1 语法select 查询列 from 表1 别名1 [inner] join 表2 别名2 on 连接条件 where 普通过滤条件;join默认就是inner join内连接只返回两边能够匹配的行。from a, b where ...也能表达内连接但工程中推荐显式join ... on因为它把连接条件与普通过滤分开更不容易漏写条件3.2 表别名与列歧义多个表都有id、name时裸写列名可能出现错误 1052。应使用短别名和别名.列名selects.idasstudent_id,s.nameasstudent_name,c.class_namefromstudent_design2 sjoinclass_design2 conc.ids.class_idwheres.name孙悟空;3.3 三表、四表连接查询每名学生的课程与成绩selects.sno,s.name,c.course_name,sc.scorefromstudent_design2 sjoinscore_design2 sconsc.student_ids.idjoincourse_design2 conc.idsc.course_idorderbys.id,c.id;每增加一张表都要确认连接列和连接基数结果异常时检查条件、列和源数据。3.4 连接后分组统计每名学生已出分课程数和平均分selects.id,s.name,count(sc.score)asgraded_count,avg(sc.score)asavg_scorefromstudent_design2 sjoinscore_design2 sconsc.student_ids.idgroupbys.id,s.name;count(sc.score)不统计NULL适合统计已出分课程count(*)统计结果行。开启only_full_group_by时查询列应参与分组、被聚合或能被分组列函数依赖4. 外连接 OUTER JOIN4.1 左连接与右连接-- 保留左表全部行 select ... from 表1 left join 表2 on 连接条件; -- 保留右表全部行 select ... from 表1 right join 表2 on 连接条件;left join保留左表全部行右侧无匹配时补NULL。交换表顺序即可把右连接改为左连接项目中统一左连接通常更易读统计所有班级人数包括 0 人班级selectc.id,c.class_name,count(s.id)asstudent_countfromclass_design2 cleftjoinstudent_design2 sons.class_idc.idgroupbyc.id,c.class_name;必须用count(s.id)若用count(*)外连接产生的空行会让空班级被统计为 14.2 查找“没有关联记录”的数据查找没有任何选课记录的学生selects.id,s.sno,s.namefromstudent_design2 sleftjoinscore_design2 sconsc.student_ids.idwheresc.student_idisnull;应检查右表中本来就不允许为NULL的主键或外键列。不要用sc.score is null判断“没有记录”因为本系统允许score为NULL表示已选课但尚未出分。这叫反连接模式也可用not exists表达4.3 ON 与 WHERE 的关键区别on决定如何匹配where过滤连接后的结果。右表条件放在where中会删除补出的NULL行使左连接近似退化为内连接-- 只返回存在及格成绩的学生selects.name,sc.scorefromstudent_design2 sleftjoinscore_design2 sconsc.student_ids.idwheresc.score60;要保留所有学生只匹配及格成绩应把条件写入onselects.name,sc.scorefromstudent_design2 sleftjoinscore_design2 sconsc.student_ids.idandsc.score60;4.4 全外连接MySQL 8.0 没有原生full outer join可用“左连接 反向左连接的未匹配部分”selecta.id,b.idfromtable_a aleftjointable_b bonb.ida.idunionallselecta.id,b.idfromtable_b bleftjointable_a aona.idb.idwherea.idisnull;5. 自连接 SELF JOIN自连接不是新关键字而是同一张表在一个查询中扮演不同角色必须使用不同别名。比较同一学生的 MySQL 与 Java 成绩selects.name,m.scoreasmysql_score,j.scoreasjava_scorefromscore_design2 mjoinscore_design2 jonj.student_idm.student_idjoinstudent_design2 sons.idm.student_idjoincourse_design2 cmoncm.idm.course_idjoincourse_design2 cjoncj.idj.course_idwherecm.course_nameMySQLandcj.course_nameJavaandm.scorej.score;用m、j区分两种成绩用student_id保证比较同一学生。6. 子查询子查询嵌套在另一条语句中其用法取决于返回一个值、一行、多行还是结果表。6.1 标量子查询返回一个值查询高于全体平均分的成绩selectstudent_id,course_id,scorefromscore_design2wherescore(selectavg(score)fromscore_design2);单值比较要求子查询至多返回一行一列返回多行会出现错误 1242。6.2 多行子查询IN查询 Java 或 MySQL 课程的成绩select*fromscore_design2wherecourse_idin(selectidfromcourse_design2wherecourse_namein(Java,MySQL));in表示等于集合中的任意值。若子查询含NULLnot in可能得到unknown而查不到行排除关联记录时优先用not exists或显式排除NULL。6.3 EXISTS 与关联子查询查询至少选过一门课的学生selects.id,s.namefromstudent_design2 swhereexists(select1fromscore_design2 scwheresc.student_ids.id);内层引用外层s.id属于关联子查询。exists只判断匹配行是否存在没有选课则用not exists。子查询不一定比连接慢。MySQL 可能将in、exists转为半连接或物化结果应通过执行计划验证。6.4 多列子查询行构造器可让多个列作为一个整体比较select*fromscore_demowhere(student_id,course_id,score)in(selectstudent_id,course_id,scorefromscore_demogroupbystudent_id,course_id,scorehavingcount(*)1);内外列的数量、顺序、类型须对应。正式表已有复合主键重复选课应在写入时被拒绝6.5 FROM 中的子查询与 CTEfrom中的子查询称为派生表MySQL 要求给它别名selectt.class_id,t.avg_scorefrom(selects.class_id,avg(sc.score)asavg_scorefromstudent_design2 sjoinscore_design2 sconsc.student_ids.idgroupbys.class_id)twheret.avg_score80;MySQL 8.0 还可用with 名称 as (子查询)定义 CTE提高复杂查询可读性。派生表或 CTE 不代表一定创建磁盘临时表优化器可能合并它也可能物化后使用6.6 如何选择返回关联表列用join判断存在性用exists与单值比较用标量子查询与集合比较用in复杂逻辑可用 CTE。先保证语义清楚再验证性能7. 集合查询连接是在同一行上横向补列集合操作把多个查询的结果纵向叠加7.1 UNION 与 UNION ALLselectsno,namefromcurrent_studentunionselectsno,namefromarchived_student;selectsno,namefromcurrent_studentunionallselectsno,namefromarchived_student;union默认去除完全相同的结果行需要额外的去重工作union all保留重复行通常更快业务允许重复时优先考虑各查询必须返回相同列数同一位置的数据类型应兼容最终列名取第一个查询的列名或别名整体排序应在最后写一次并使用最终结果的列名selectsno,namefromcurrent_studentunionallselectsno,namefromarchived_studentorderbysno;7.2 MySQL 8.0.31 之后的集合运算MySQL 8.0.31 新增intersect交集和except差集查询1 intersect [all | distinct] 查询2; 查询1 except [all | distinct] 查询2;8.0.39 支持旧版需用连接改写。集合运算默认distinct。8. 保存查询结果8.1 INSERT … SELECT把查询结果插入已有表insertintoexcellent_student(student_id,avg_score)selectstudent_id,avg(score)fromscore_design2groupbystudent_idhavingavg(score)90;目标列与查询列的数量、顺序、类型须对应并应显式写目标列名。目标表约束仍会执行自增列通常省略它只复制数据。大量迁移前先单独核对select并按原子性要求使用事务8.2 CREATE TABLE … SELECT根据查询结果直接创建新表createtableclass_score_reportasselects.class_id,count(sc.score)asgraded_count,avg(sc.score)asavg_scorefromstudent_design2 sjoinscore_design2 sconsc.student_ids.idgroupbys.class_id;它适合临时报表但不会自动创建索引auto_increment等属性也可能丢失表达式应起别名。复制同构表通常使用createtablestudent_backuplikestudent_design2;insertintostudent_backupselect*fromstudent_design2;like复制字段属性和索引但不复制外键完成后用show create table检查9. 用 EXPLAIN 理解执行计划不要凭 SQL 外观猜性能应查看执行计划explainanalyzeselects.name,sc.scorefromstudent_design2 sjoinscore_design2 sconsc.student_ids.id;explain展示估算计划explain analyze会实际执行并显示行数与耗时不要对高风险语句随意使用重点检查实际连接顺序及各步读取行数key是否使用预期索引是否出现不必要的ALL扫描估算与实际行数是否差异很大是否出现 Hash Join、临时表、排序或大量循环连接列两侧类型应一致被驱动表的连接列需要可用索引复合索引应依据真实筛选和排序设计。索引会增加写入成本并非越多越好10. 常见错误与排查现象常见原因检查方法结果行数异常巨大漏写条件或误判连接基数分步连接并统计行数错误 1052多表存在同名列使用表别名.列名左连接查不到无匹配行右表条件写进了where判断条件是否应移入on无记录被误判检查了可为NULL的业务列检查右表非空主键/外键错误 1242标量子查询返回多行改用in或保证只返回一行not in意外返回空集子查询含NULL改用not exists或排除NULLunion报列数错误各查询列数不同逐个执行并核对列的位置聚合结果偏大连接先重复了事实行确认表粒度和连接基数排查时先验证单表条件再一次加入一张表和一个on比较每步行数最后添加分组与排序。连接错误进入聚合后常只留下看似合理的错误数字11. 综合查询查询所有学生的班级、已选课程数、平均分并保留没有选课的学生selects.id,s.sno,s.name,c.class_name,count(sc.course_id)ascourse_count,round(avg(sc.score),2)asavg_scorefromstudent_design2 sjoinclass_design2 conc.ids.class_idleftjoinscore_design2 sconsc.student_ids.idgroupbys.id,s.sno,s.name,c.class_nameorderbyavg_scoredesc,s.id;设计原因学生必须属于有效班级所以学生与班级使用内连接。学生可以暂时没有选课所以成绩使用左连接。count(sc.course_id)让无选课学生得到 0而不是 1。avg忽略未出分的NULL没有有效成绩时仍为NULL不同于 0 分。聚合发生在连接之后因此分组必须与“一名学生一行”的目标粒度一致。参考MySQL 8.0嵌套循环连接MySQL 8.0Hash Join 优化MySQL 8.0子查询优化MySQL 8.0UNIONMySQL 8.0INSERT … SELECTMySQL 8.0CREATE TABLE … SELECTMySQL 8.0使用 EXPLAIN 优化查询以上是我关于MySQL的笔记分享也可以关注关注我的Syrena-Blog感谢你读到这里这也是我学习路上的一个小小记录。希望以后回头看时能看到自己的成长

相关推荐

e盒印网站开发实战案例:3步搞定备案与设计落地
e盒印网站开发实战案例:3步搞定备案与设计落地

e盒印网站开发实战案例:3步搞定备案与设计落地 刚接了个e盒印的定制站单子,客户第一句话不是问价格,是问:“备案到底怎么弄?我看了一堆资料还是觉得一头雾水。” 这种场景太常见了。很多设计师转前端,或者刚入行的开发,代码写得飞起,一碰到… · 2026/9/27 11:18:30

MySQL数据库:索引
MySQL数据库:索引

适用环境:MySQL 8.0,存储引擎以 InnoDB 为主。 索引的最终目标不是“数量多”,而是让常用查询以更少的页面访问得到更少的候选行。 1. 索引 索引是存储引擎维护的、有序的数据结构。它保存索引键及定位记录所需的信息,使 MySQL 不… · 2026/9/27 11:18:30

第一次学 LangGraph:用一个快递案例搞懂 State、Node、Edge 和 compile
第一次学 LangGraph:用一个快递案例搞懂 State、Node、Edge 和 compile

我挖掘了一个巨牛的 人工智能 学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站 如果你刚开始学习 LangGraph,大概率会遇到这样一种感觉: State、Node、Edge、START、END、compile……每个单词单独… · 2026/9/27 11:18:24

网站建设行业怎么样:3个免费工具搞定备案与部署
网站建设行业怎么样:3个免费工具搞定备案与部署

网站建设行业怎么样:3个免费工具搞定备案与部署 别再对着那些千篇一律的模板网站叹气,真的不够看。很多创业团队负责人跟我抱怨,花了大价钱找外包,做出来的官网像上世纪的产物,既丑又慢,根本留不住客户。更扎心的是,想自己折腾,又觉得域名、服务器、… · 2026/9/27 11:58:49

做网站平台成本一文搞懂:小白避坑指南
做网站平台成本一文搞懂:小白避坑指南

做网站平台成本一文搞懂:小白避坑指南 自己不会代码想做网站,最怕的就是钱花了没效果。别慌,这篇 一文搞懂 做网站平台成本,帮你算清账。很多新手一上来就找开发公司,报价动辄几万,其实大可不必。… · 2026/9/27 11:58:43

本地 AI Agent 平台实测:以 QClaw 为例,聊聊这类工具的优势与局限
本地 AI Agent 平台实测:以 QClaw 为例,聊聊这类工具的优势与局限

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 11:58:37

STM32开发避坑指南:如何高效筛选可信参考方案
STM32开发避坑指南:如何高效筛选可信参考方案

1. 为什么“找参考方案”这件事,比写代码更耗新人三个月刚接触 STM32 的朋友常有个错觉:只要装好 Keil、烧进程序、LED 亮了,就算入门了。我带过十几届电子类毕业设计学生,也帮过上百个嵌入式转岗工程师调试板子,发现一… · 2026/9/27 11:58:31

嵌入式C++开发工具链原理:从交叉编译到STM32调试全解析
嵌入式C++开发工具链原理:从交叉编译到STM32调试全解析

1. “装了四个软件却不知道是干嘛的”——这根本不是你的问题,是嵌入式C入门最真实的挫败感你刚在VS Code里点完“Install”按钮,电脑弹出四个安装窗口:ARM GNU Toolchain、STM32CubeMX、OpenOCD、ST-Link Utility。你照着某篇教程一步步操作… · 2026/9/27 11:58:24

深圳网站推广优化培训全解:新手入门完整流程
深圳网站推广优化培训全解:新手入门完整流程

深圳网站推广优化培训全解:新手入门完整流程 网站做好了没人访问,这是很多深圳中小企业老板最头疼的事。很多新手以为只要找个公司把站建好,流量就会像自来水一样哗哗来,结果上线一个月,百度搜不到,谷歌没排名,客户更是零咨询。这种焦虑背后,往往是因… · 2026/9/27 11:58:24

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码