在实际开发和面试中,多表查询是SQL的核心考点之一。业务中几乎不可能只靠单表完成所有需求,因此掌握JOIN和子查询是每个工程师的必备技能。本文总结了多表查询的常用写法,既能作为学习笔记,也能在面试中快速回忆。

一、为什么要用多表查询?

真实业务中,数据往往分散在不同表中,例如用户表和订单表。

查询用户的订单信息,就需要把这两张表的数据结合在一起。

SQL提供了JOIN和子查询两大手段,灵活完成多表数据整合。

二、JOIN 详解

1. INNER JOIN(内连接)

取两张表中匹配成功的数据。

SELECT u.id, u.name, o.order_id, o.amount

FROM users u

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

👉 只有users和orders同时匹配到的行才会被返回。

2. LEFT JOIN(左连接)

以左表为主,返回左表全部数据,如果右表没有匹配,则填充为NULL。

SELECT u.id, u.name, o.order_id

FROM users u

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

👉 即使某些用户没有订单,也会出现在结果里。

3. RIGHT JOIN(右连接)

和LEFT JOIN相反,以右表为主,返回右表全部数据。

SELECT u.id, u.name, o.order_id

FROM users u

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

4. FULL JOIN(全连接)

返回两张表的所有数据,匹配不上的部分填NULL。

⚠️ 注意:MySQL不直接支持FULL JOIN,可以通过UNION组合LEFT JOIN和RIGHT JOIN来实现。

三、子查询(Subquery)

子查询是写在另一个SQL里的SQL。常见用法有三类:

1. 标量子查询

子查询返回单个值,常用于比较。

SELECT name, salary

FROM employees

WHERE salary > (SELECT AVG(salary) FROM employees);

👉 查询工资高于平均工资的员工。

2. 列子查询

子查询返回一列,常用于IN。

SELECT name

FROM users

WHERE id IN (SELECT user_id FROM orders WHERE amount > 100);

👉 查询下过大额订单的用户。

3. 表子查询

子查询返回一张临时表,可以继续JOIN或SELECT。

SELECT t.user_id, COUNT(*) AS order_count

FROM (SELECT user_id FROM orders WHERE status = 'paid') t

GROUP BY t.user_id;

👉 查询所有已支付订单的用户及订单数。

四、ON和WHERE的区别

很多初学者容易混淆ON和WHERE的区别。

ON:在表连接阶段起作用,决定两表如何匹配。

WHERE:在连接完成后过滤结果。

举个例子:

SELECT u.id, u.name, o.order_id

FROM users u

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

WHERE o.amount > 100;

👉 注意,这里WHERE o.amount > 100会把没有订单的用户也过滤掉,效果相当于INNER JOIN。

如果要保留没有订单的用户,应该把条件写在ON后面。

五、面试高频考点

1. INNER JOIN和LEFT JOIN的区别?

答:INNER JOIN只保留匹配行,LEFT JOIN保留左表全部行。

2. 子查询和JOIN的区别?

答:子查询可读性高,JOIN性能更好;面试时可提到“优化时更倾向于JOIN”。

3. ON和WHERE的执行顺序?

答:ON先于WHERE执行,影响结果集范围。

六、总结

多表查询核心两大工具:JOIN和子查询。

JOIN主要分为INNER、LEFT、RIGHT、FULL,不同场景灵活选择。

子查询分为标量、列、表三种类型。

注意ON和WHERE的区别,这是面试的常见考点。

掌握这些写法,能解决大多数业务查询问题,也是面试必问的重点。

💡 建议:多写实际SQL,多用EXPLAIN分析执行计划,才能真正理解JOIN的性能差异。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐