SQL: 多表连接与跨表查询(JOIN)
- 经典回顾
- 2025-11-30 20:33:30
- 7078
目录
什么是 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),表示这些字段有非空约束,也是外键,指向其他表的主键。
(实际上,所有带有任何填充颜色的钻石图标,都意味着这个字段具有非空约束)