当前位置: 首页 > 测试知识 > 软件数据库MySQL联表查询指南
软件数据库MySQL联表查询指南
2026-06-15 作者cwb 浏览次数51

MySQL联表查询的完整指南,包括连接类型、语法、使用场景和常见问题。


1. 连接类型概览

INNER JOIN(内连接):返回两个表中一致行。

LEFT JOIN(左外连接):返回左表所有行,右表无一致时填充 NULL。

RIGHT JOIN(右外连接):返回右表所有行,左表无一致时填充 NULL(可用 LEFT JOIN 替代,更易读)。

FULL OUTER JOIN:返回两表所有行,无一致处填充 NULL。MySQL 不直接支持,需用 LEFT JOIN UNION RIGHT JOIN 模拟。

CROSS JOIN(交叉连接):返回笛卡尔积(所有组合)。

SELF JOIN(自连接):表和自身连接,必须使用别名。

2. 基本语法和示例


INNER JOIN

sql

SELECT u.name, o.order_no

FROM users u

INNER JOIN orders o ON u.id = o.user_id;


只返回有订单的用户。当条件写在 ON 中时,它既是连接条件也是过滤条件;对于内连接,ON 和 WHERE 结果等价。


LEFT JOIN

sql

SELECT u.name, o.order_no

FROM users u

LEFT JOIN orders o ON u.id = o.user_id;


所有用户都会出现,没有订单的用户对应的 order_no 为 NULL。常见需求:找出没有订单的用户:

sql

SELECT u.name

FROM users u

LEFT JOIN orders o ON u.id = o.user_id

WHERE o.user_id IS NULL;


RIGHT JOIN

sql

SELECT o.order_no, u.name

FROM orders o

RIGHT JOIN users u ON o.user_id = u.id;


效果和上面的 LEFT JOIN 完全相同,但左右表角色互换。建议统一使用 LEFT JOIN,思维负担更小。


模拟 FULL OUTER JOIN


sql

SELECT u.name, o.order_no

FROM users u

LEFT JOIN orders o ON u.id = o.user_id

UNION

SELECT u.name, o.order_no

FROM users u

RIGHT JOIN orders o ON u.id = o.user_id;


返回所有用户和所有订单,不一致的侧补 NULL。


CROSS JOIN

sql

SELECT a.color, b.size

FROM colors a

CROSS JOIN sizes b;


生成所有颜色和尺码的组合,常用于生成测试数据或组合矩阵。可省略 CROSS JOIN 直接写逗号连接,但显式写法更清晰。


SELF JOIN

sql

SELECT e.name AS employee, m.name AS manager

FROM employees e

LEFT JOIN employees m ON e.manager_id = m.id;


同一张表用不同别名区分角色。


3. ON和USING的区别

ON:适用于列名不同或需要复杂条件的场景。


sql

LEFT JOIN orders o ON u.id = o.user_id AND o.status = 'paid'


USING:当两表的连接列同名时可简化写法,自动合并重复列。


sql

SELECT * FROM users JOIN orders USING (user_id);


结果中 user_id 只出现一次。使用 USING 时,引用该列无需加表别名。


4. 多表连接

可以一次性连接多张表,按顺序书写即可。

sql

SELECT u.name, o.order_no, p.product_name

FROM users u

JOIN orders o ON u.id = o.user_id

JOIN order_items oi ON o.id = oi.order_id

JOIN products p ON oi.product_id = p.id

WHERE u.vip = 1;


执行顺序:先 users 和 orders 连接,再和 order_items 连接,最后和 products 连接。适当调整连接顺序有时能优化性能。


5. 连接条件和 WHERE 条件的区别

对于 INNER JOIN:ON 和 WHERE 没有思路差别,但建议把关联条件放 ON,业务过滤放 WHERE,更易读。

对于 LEFT/RIGHT JOIN:两者语义完全不同。

写在 ON 中的条件是连接时过滤右表,不影响左表行数。

写在 WHERE 中是对连接后的结果集进行过滤,可能把左表不一致的行也过滤掉。


示例:查询所有用户,以及他们已支付的订单(未支付的不显示订单信息,但用户还在):

sql

SELECT u.name, o.order_no

FROM users u

LEFT JOIN orders o ON u.id = o.user_id AND o.status = 'paid';


如果把 o.status = 'paid' 移到 WHERE,则只有存在已支付订单的用户才会被保留,其他用户被过滤掉。


6. 性能优化

为连接列建立索引:JOIN 的条件列、WHERE 过滤列都应有索引,尤其是被驱动表的连接列。

小表驱动大表:一般让结果集较小的表作为驱动表(写在 JOIN 前面),但优化器会自行调整,可通过 STRAIGHT_JOIN 强制指定。

避免笛卡尔积:缺少 ON 条件的 CROSS JOIN 会产生巨大结果集,确定业务需要。

检查 NULL 的思路:使用 LEFT JOIN 后判断“不存在”时,用 IS NULL 不要用 = NULL。

注意重复行:一对多连接会使结果行数倍增,聚合计算前要用 DISTINCT 或子查询去重。

连接数不宜过多:一次性连接五六张表以上时,考虑分步查询或使用临时表,避免执行计划恶化。


文章标签: 数据库测试 软件测试
咨询软件测试