SQL JOIN 全解析:跨表查询与实体关系建模
目录
跨表组合数据(JOIN)
🔗 什么是 JOIN?
🔗 为什么要用 JOIN?
基本语法:
表别名(o, c, p 是什么?)
常见 JOIN 类型总结
JOIN 多个表
创建实体关系图(ERD)
跨表组合数据(JOIN)
🔗 什么是 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
→ JOINcustomers
-
orders
有product_id
→ JOINproducts
这叫连接路径是明确的,你不能跳着连,要层层跟上。
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.你可以在这个界面中拖动、调整表的位置,并右键表查看表结构