MySQL多表查询是指通过关联多个数据表来获取所需数据的查询方式,实际业务场景中用户表、订单表、商品表等往往存在关联关系,单表查询无法完整获取业务所需信息,因此需要掌握多表查询的相关用法。

多表查询基础:笛卡尔积
当直接查询多个表时,如果不指定关联条件,会产生笛卡尔积,即第一个表的每一行都会和第二个表的所有行组合,结果行数为两个表行数的乘积,这种结果通常没有实际业务意义,示例代码如下:
-- 假设存在user表和order表,直接查询两个表会产生笛卡尔积 SELECT * FROM user, order_table;
实际使用中需要避免无意义的笛卡尔积,通常需要通过关联条件来筛选有效数据。
连接查询
内连接(INNER JOIN)
内连接会返回两个表中满足关联条件的交集数据,也就是两个表都匹配的行才会被返回,是最常用的连接类型。语法上可以使用INNER JOIN关键字,也可以直接在WHERE子句中指定关联条件。
假设我们有两个表,用户表user结构如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | int | 用户ID,主键 |
| username | varchar(50) | 用户名 |
| age | int | 用户年龄 |
订单表order_table结构如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| order_id | int | 订单ID,主键 |
| user_id | int | 用户ID,关联user表的id |
| order_amount | decimal(10,2) | 订单金额 |
查询有订单的用户及其订单信息的内连接示例:
-- 使用INNER JOIN关键字的标准写法 SELECT u.id, u.username, o.order_id, o.order_amount FROM user u INNER JOIN order_table o ON u.id = o.user_id; -- 旧式写法,在WHERE中指定关联条件,效果和上面一致 SELECT u.id, u.username, o.order_id, o.order_amount FROM user u, order_table o WHERE u.id = o.user_id;
左连接(LEFT JOIN)
左连接会返回左表的所有行,即使右表中没有匹配的行,右表没有匹配的部分会显示为NULL。适合需要查询左表全部数据,同时关联右表匹配数据的场景,比如查询所有用户及其订单信息,包括没有下单的用户。
SELECT u.id, u.username, o.order_id, o.order_amount FROM user u LEFT JOIN order_table o ON u.id = o.user_id;
右连接(RIGHT JOIN)
右连接和左连接逻辑相反,会返回右表的所有行,左表没有匹配的部分显示为NULL,实际使用中可以通过调整表的顺序用左连接替代,使用频率相对较低。
SELECT u.id, u.username, o.order_id, o.order_amount FROM user u RIGHT JOIN order_table o ON u.id = o.user_id;
全连接(FULL JOIN)
MySQL本身不支持FULL JOIN关键字,但是可以通过左连接和右连接的结果取并集来实现全连接的效果,返回两个表的所有行,没有匹配的部分显示为NULL。
-- 使用UNION合并左连接和右连接的结果实现全连接 SELECT u.id, u.username, o.order_id, o.order_amount FROM user u LEFT JOIN order_table o ON u.id = o.user_id UNION SELECT u.id, u.username, o.order_id, o.order_amount FROM user u RIGHT JOIN order_table o ON u.id = o.user_id;
子查询
子查询是指在一个查询语句中嵌套另一个查询语句,嵌套的查询称为子查询,外层的查询称为主查询。子查询可以放在WHERE子句、FROM子句等位置,根据返回结果的不同可以分为标量子查询、列子查询、行子查询和表子查询。
标量子查询
标量子查询返回单个值,通常用在WHERE子句的比较条件中,比如查询订单金额大于平均订单金额的所有订单:
SELECT * FROM order_table WHERE order_amount > (SELECT AVG(order_amount) FROM order_table);
列子查询
列子查询返回一列多行的结果,通常配合IN、ANY、ALL等关键字使用,比如查询有订单的所有用户信息:
SELECT * FROM user WHERE id IN (SELECT user_id FROM order_table);
表子查询
表子查询返回多行多列的结果,通常放在FROM子句中作为临时表使用,比如查询每个用户的订单数量:
SELECT u.id, u.username, t.order_count
FROM user u
LEFT JOIN (
SELECT user_id, COUNT(*) AS order_count
FROM order_table
GROUP BY user_id
) t ON u.id = t.user_id;
多表查询注意事项
- 关联查询时要明确指定关联条件,避免产生无意义的笛卡尔积,影响查询性能。
- 连接查询时如果表名较长,可以使用表别名简化书写,提升代码可读性。
- 子查询的性能通常不如连接查询,在数据量较大的场景下,优先考虑使用连接查询替代子查询。
- 如果查询涉及多个表的同名字段,必须使用表名或表别名前缀区分,避免出现字段歧义错误。
多表查询是MySQL处理复杂业务数据的核心能力,熟练掌握各类连接查询和子查询的用法,能够根据实际业务场景选择最合适的查询方式,是数据库开发的基础技能。
MySQL多表查询inner_joinleft_join子查询修改时间:2026-06-29 22:24:27