首页  > 经典回顾

SQL: 多表连接与跨表查询(JOIN)

目录

什么是 JOIN?

为什么要用 JOIN?

基本语法:

表别名(o, c, p 是什么?)

常见 JOIN 类型总结

JOIN 多个表

创建实体关系图(ERD)

修饰记号含义

什么是 JOIN?

JOIN 是用来连接两个或多个表的操作,它基于表之间的关系(通常是外键),将它们的记录“拼接”起来,它让你能在多个表之间组合数据。

我们仍然以coffee_store 数据库为例,里面有三张表:

products(id, name, price, coffee_orgin)

customers(id, first_name, last_name, gender, phone_number)

orders(id, product_id, customer_id, order_time)

customers ←── orders ──→ products

product_id

customer_id

为什么要用 JOIN?

你把商品信息放在 products 表里,把客户信息放在 customers 表里,订单记录放在 orders 表里。 而你想问的问题是:“某个客户买了什么商品?” —— 这个就必须用 JOIN 把多个表连接起来。

基本语法:

SELECT 列1, 列2, ...FROM 表A

JOIN 表B ON 表A.列名 = 表B.列名;

#表A为左表 ,表B为右表

表别名(o, c, p 是什么?)

在 JOIN 中我们常使用表别名(alias),提高代码可读性。 示例:

FROM orders AS o

JOIN customers AS c ON o.customer_id = c.id

含义是:

o 是 orders 的简称

c 是 customers 的简称

写别名的目的是为了避免重复表名前缀,尤其在多表连接中非常有用。

常见 JOIN 类型总结

JOIN 类型说明是否保留未匹配行INNER JOIN两边都匹配才返回❌ 否LEFT JOIN返回左表所有行,右表能匹配就匹配✅ 是RIGHT JOIN返回右表所有行,左表能匹配就匹配✅ 是FULL JOIN左右都保留(MySQL 不直接支持)✅ 是

1️⃣ INNER JOIN:匹配成功才返回

SELECT o.id AS order_id, c.first_name, p.name

FROM orders AS o

INNER JOIN customers AS c ON o.customer_id = c.id

INNER JOIN products AS p ON o.product_id = p.id;

每一条记录是:某个顾客买了某个商品,在某个时间

只有当 orders 表中的 customer_id 和 product_id 都能在其它表找到匹配时才会返回

2️⃣ LEFT JOIN:保留左表所有数据

无论右表是否有匹配,左表的记录都保留

右表没有匹配时,对应的字段值为 NULL

SELECT o.id AS order_id, p.name AS product_name

FROM orders AS o

LEFT JOIN products AS p ON o.product_id = p.id;

订单表是左边,哪怕某个 product_id 在 products 表中找不到匹配(比如产品被删了),这条订单仍然会被显示,只是 product_name 是 NULL。

3️⃣ RIGHT JOIN(较少使用)

SELECT c.first_name, o.id AS order_id

FROM orders AS o

RIGHT JOIN customers AS c ON o.customer_id = c.id;

保留 customers 中的所有客户,即使他们没下订单。

JOIN 多个表

多表 JOIN 的语法结构

SELECT ...

FROM 表1

JOIN 表2 ON 表1.字段 = 表2.字段

JOIN 表3 ON 表2.字段 = 表3.字段

...

注意:JOIN 是“逐步连接”的过程,每次 JOIN 两张表,最后形成一张大表。

☕ 示例:联查顾客名字、产品名称、订单时间

SELECT

c.first_name,

c.last_name,

p.name AS product_name,

p.price,

o.order_time

FROM orders AS o

JOIN customers AS c ON o.customer_id = c.id

JOIN products AS p ON o.product_id = p.id;

主表:orders(订单是中间表,连接顾客和商品)

第一步 JOIN customers:o.customer_id = c.id

第二步 JOIN products:o.product_id = p.id

为什么要“逐个 JOIN”?

因为每个 JOIN 的条件都必须基于当前已有的表结构去连接新表。举例:

orders 有 customer_id → JOIN customers

orders 有 product_id → JOIN products

这叫连接路径是明确的,你不能跳着连,要层层跟上。

JOIN 顺序是否重要?

语义上不重要,但实际写法上有讲究:

如果你把 orders 放在最前,连接 customers 和 products 就很自然

否则你要调整连接条件,比如:

FROM customers c

JOIN orders o ON c.id = o.customer_id

JOIN products p ON o.product_id = p.id

也是可以的,关键是 ON 条件要对!

创建实体关系图(ERD)

在 MySQL Workbench 中创建 Entity Relationship Diagram(ERD) 是非常实用的功能,适合可视化数据库结构。

步骤:

打开 MySQL Workbench

连接进入你的数据库

菜单栏点击:Database > Reverse Engineer

4.出现导入向导:

选择数据库连接 ✅

选择要导入的 schema(比如 coffee_store)✅

点击下一步,直到完成

5. 成功后,Workbench 会为你生成一张 ER 图,展示所有表及其主外键关系

6.你可以在这个界面中拖动、调整表的位置,并右键表查看表结构

修饰记号含义

图中带金钥匙图标的字段(如 id),表示该字段是主键,用于唯一标识表中的每一行数据。

图中带蓝绿色钻石图标的字段(如 name,length_min),表示这些字段有非空约束(NOT NULL)。

图中带红色钻石图标的字段(如 film_id, room_id),表示这些字段有非空约束,也是外键,指向其他表的主键。

(实际上,所有带有任何填充颜色的钻石图标,都意味着这个字段具有非空约束)