news 2026/2/10 21:05:49

MySQL中多表查询的方式有哪些?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MySQL中多表查询的方式有哪些?

一、先明确:为什么必须掌握多表查询?

1.你是否能区分不同多表查询方式的差异?
2.能否根据业务场景选择合适的查询方式?
3.能否独立写出正确的多表查询 SQL?(避免语法错误)

二、先铺垫:多表查询的基础前提

先明确多表查询的核心:表与表之间必须有 “关联关系”(通常是主键 - 外键关联,比如用户表user的id(主键)对应订单表order的user_id(外键)),没有关联关系的多表查询会产生 “笛卡尔积”(数据冗余,无实际业务意义)。

先定义两个测试表:

-- 用户表(主表) CREATE TABLE `user` ( `id` INT PRIMARY KEY AUTO_INCREMENT, -- 用户ID(主键) `username` VARCHAR(50) NOT NULL, -- 用户名 `age` INT DEFAULT 0 -- 年龄 ); -- 订单表(从表) CREATE TABLE `order` ( `id` INT PRIMARY KEY AUTO_INCREMENT, -- 订单ID(主键) `order_no` VARCHAR(30) NOT NULL, -- 订单编号 `user_id` INT NOT NULL, -- 关联用户表的用户ID(外键) `price` DECIMAL(10,2) NOT NULL, -- 订单金额 FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) -- 外键约束 );

三、核心多表查询方式拆解

方式 1:JOIN 连接查询

JOIN是多表查询的核心方式,通过关联字段将多个表 “拼接” 在一起查询,核心分为内连接、外连接(左外连接、右外连接)、交叉连接(极少用,仅作了解)。

1.1 内连接(INNER JOIN / JOIN)

通俗定义:只查询 “两张表中满足关联条件” 的数据,不满足条件的记录会被过滤掉(相当于 “取两张表的交集”)。

语法:SELECT 字段 FROM 表1 INNER JOIN 表2 ON 表1.关联字段 = 表2.关联字段 [WHERE 条件](INNER可省略,直接写JOIN)。

-- 简洁写法(省略INNER) SELECT u.id AS user_id, u.username, o.id AS order_id, o.order_no, o.price FROM `user` u JOIN `order` o ON u.id = o.user_id; -- 关联条件:用户ID=订单的用户ID

考察点:你是否知道ON用于指定表关联条件,WHERE用于过滤查询结果(避免把关联条件写在WHERE中)。

1.2 左外连接(LEFT JOIN / LEFT OUTER JOIN)

通俗定义:以 “左表” 为基准,查询左表的所有数据,右表中满足关联条件的数据会被匹配显示,不满足条件的右表字段显示NULL(相当于 “左表全量数据 + 右表交集数据”)。

语法:SELECT 字段 FROM 左表 LEFT JOIN 右表 ON 关联条件 [WHERE 条件](OUTER可省略)。

SELECT u.id AS user_id, u.username, o.id AS order_id, o.order_no, o.price FROM `user` u LEFT JOIN `order` o ON u.id = o.user_id;

考察点:能否区分左表和右表,理解 “右表不满足条件显示 NULL” 的特性。

1.3 右外连接(RIGHT JOIN / RIGHT OUTER JOIN)

通俗定义:以 “右表” 为基准,查询右表的所有数据,左表中满足关联条件的数据会被匹配显示,不满足条件的左表字段显示NULL(相当于 “右表全量数据 + 左表交集数据”),功能上可通过左连接互换表位置实现。

语法:SELECT 字段 FROM 左表 RIGHT JOIN 右表 ON 关联条件 [WHERE 条件](OUTER可省略)。

SELECT u.id AS user_id, u.username, o.id AS order_id, o.order_no, o.price FROM `user` u RIGHT JOIN `order` o ON u.id = o.user_id;

考察点:知道右连接的存在,理解其与左连接的对称关系。

1.4 交叉连接(CROSS JOIN,极少用)

通俗定义:无关联条件的连接,会产生两张表的 “笛卡尔积”(数据行数 = 表 1 行数 × 表 2 行数),通常无实际业务意义,仅在特殊场景(比如生成测试数据)使用。
• SQL 示例:

-- 产生笛卡尔积,慎用 SELECT u.username, o.order_no FROM `user` u CROSS JOIN `order` o;

方式 2:子查询(嵌套查询,适合简单场景)

通俗定义:将一个查询语句(子查询 / 内层查询)嵌套在另一个查询语句(主查询 / 外层查询)中,子查询的结果作为主查询的条件或数据源,分为 “关联子查询” 和 “非关联子查询”。

非关联子查询:子查询可独立执行,结果不依赖主查询(适合简单条件过滤)

  • 示例:查询 “购买过订单金额大于 100 元的用户” 信息
SELECT id, username, age FROM `user` WHERE id IN ( -- 子查询:获取订单金额>100的所有用户ID SELECT DISTINCT user_id FROM `order` WHERE price > 100 );

关联子查询:子查询依赖主查询的字段,无法独立执行(适合 “按主表每条记录匹配子表” 的场景)

  • 示例:查询 “每个用户的最新订单”(按订单 ID 倒序取第一条)
SELECT u.id AS user_id, u.username, o.id AS order_id, o.order_no, o.price FROM `user` u JOIN `order` o ON u.id = o.user_id WHERE o.id = ( -- 子查询:关联主表的user_id,取该用户最大订单ID(最新订单) SELECT MAX(id) FROM `order` WHERE user_id = u.id );

考察点:能否区分关联 / 非关联子查询,知道子查询的适用边界(避免多层嵌套导致性能问题)。

方式 3:联合查询(UNION / UNION ALL,结果集合并)

通俗定义:将多个SELECT查询的结果集合并成一个结果集,要求所有查询的 “字段数量、字段类型、字段顺序” 一致,分为UNION(去重,会过滤重复记录)和UNION ALL(不去重,性能更高)。

语法:SELECT 字段 FROM 表1 [WHERE 条件] UNION [ALL] SELECT 字段 FROM 表2 [WHERE 条件];

-- UNION:去重(自动过滤重复的用户记录) SELECT id, username, age FROM `user` WHERE age > 25 UNION SELECT u.id, u.username, u.age FROM `user` u JOIN `order` o ON u.id = o.user_id WHERE o.price > 200; -- UNION ALL:不去重(性能更高,适合确定无重复数据的场景) SELECT id, username, age FROM `user` WHERE age > 25 UNION ALL SELECT u.id, u.username, u.age FROM `user` u JOIN `order` o ON u.id = o.user_id WHERE o.price > 200;

考察点:知道UNION和UNION ALL的区别,明确联合查询的字段要求。

查询方式核心特点适用场景性能优先级
INNER JOIN取两表交集,过滤无效数据关联数据必须存在的业务(如已下单用户)高(优先使用)
LEFT JOIN保留左表全量数据,右表补 NULL需显示主表所有数据的场景(如所有用户订单)
子查询嵌套查询,逻辑直观简单条件过滤(如根据子查询结果筛选主表)中(复杂场景不如 JOIN)
UNION / UNION ALL合并结果集多查询结果合并(如不同条件的同类数据)中(UNION ALL > UNION)

加分项

1、结合项目举例:“我在实训项目中,用LEFT JOIN查询所有用户及对应的订单列表,用INNER JOIN查询有支付记录的用户信息”;

2、性能意识:“复杂多表查询优先用JOIN,不用多层子查询;合并结果集时,确定无重复数据就用UNION ALL,比UNION快”;

3、细节把控:“JOIN的关联条件写在ON里,过滤条件写在WHERE里,避免笛卡尔积冗余”。

举一反三

1、“如何查询‘没有订单记录的用户’?”(答案:LEFT JOIN后判断订单字段为NULL,SELECT u.* FROM user u LEFT JOIN order o ON u.id=o.user_id WHERE o.id IS NULL);

2. “ON和WHERE在JOIN查询中有什么区别?”(答案:ON是表关联条件,先执行;WHERE是结果过滤条件,在表关联后执行;LEFT JOIN中,ON不过滤左表数据,WHERE会过滤);

3. “多表查询时,如何提高性能?”(答案:给关联字段(主键 / 外键)建索引;避免SELECT *,只查需要的字段;减少笛卡尔积产生)。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/9 1:10:43

类脑智能技术——数字CMOS型和数模混合CMOS型神经形态芯片以及基于新型器件的混合系统(下)

第三节:数模混合CMOS型神经形态芯片数模混合CMOS型神经形态芯片巧妙地结合了模拟电路的低功耗、高并行度和数字电路的可配置性、抗干扰性,试图在生物合理性、能效和工程可行性之间找到平衡。一、组成结构数模混合CMOS型神经形态芯片的核心思想是&#xf…

作者头像 李华
网站建设 2026/2/3 6:36:57

Open-AutoGLM虚拟机部署全流程解析(含自动化脚本模板限时领取)

第一章:Open-AutoGLM虚拟机部署方案概述Open-AutoGLM 是一款基于开源大语言模型的自动化推理与生成平台,支持在虚拟化环境中快速部署与扩展。该平台结合了 AutoGLM 推理引擎与轻量级服务编排能力,适用于企业级 AI 任务调度、私有化部署和边缘…

作者头像 李华
网站建设 2026/2/10 5:08:36

记录一个at6558r芯片收不到数据的问题

原来是正常可以接收数据的,然后用cube重新生成了一次代码后,发现无法接收任何数据,使用的是串口2。 然后在排查问题时候,使用最小系统版结合面包板测试串口2,收发正常,所以生成的代码是没有问题的。 然后仔细检查是波特…

作者头像 李华
网站建设 2026/2/3 7:50:25

Open-AutoGLM ModelScope镜像使用秘籍(仅限内部流传的6个高效技巧)

第一章:Open-AutoGLM ModelScope镜像的核心价值Open-AutoGLM 在 ModelScope 平台提供的镜像封装,极大简化了开发者部署与调用大语言模型的流程。该镜像集成了预配置环境、依赖库及优化后的推理引擎,使用户无需手动搭建复杂运行时即可快速启动…

作者头像 李华
网站建设 2026/2/3 20:24:26

GPU资源不足?如何在低成本虚拟机上成功部署Open-AutoGLM,抢占AI先机

第一章:GPU资源不足?重新定义低成本AI部署策略在AI模型日益庞大的今天,高性能GPU已成为训练和推理的标配。然而,对于中小团队或个人开发者而言,获取充足的GPU资源往往面临成本与可及性的双重挑战。面对这一现实&#x…

作者头像 李华
网站建设 2026/2/6 23:10:41

Open-AutoGLM环境搭建全攻略:手把手教你10分钟完成Python依赖部署

第一章:Open-AutoGLM环境搭建前的准备工作 在开始部署 Open-AutoGLM 之前,必须确保开发环境满足其运行依赖和系统要求。合理的前期准备不仅能提升安装成功率,还能避免后续调试过程中出现兼容性问题。 系统与硬件要求 操作系统:推…

作者头像 李华