SQL 联结(JOIN)详解
什么是联结?
在关系型数据库中,为了减少数据冗余、提高存储效率,通常会将数据分散存储在多个表中。联结(JOIN) 是一种机制,用于在一条 SELECT 语句中从多个表检索数据,通过表之间的关联字段将数据组合起来。
为什么使用联结?
-
避免数据重复:每个数据只在一个表中存储一次,节省空间,避免更新异常。
-
易于维护:修改某个数据时,只需更新一张表,相关表无需改动。
-
增强可伸缩性:能够适应数据量的增长和复杂查询的需求。
笛卡尔积与 WHERE 子句
当联结两个表且没有指定联结条件时,会返回笛卡尔积,第一个表的每一行与第二个表的每一行配对,结果行数为两表行数乘积。例如:
SELECT * FROM 表1, 表2; -- 无 WHERE 条件
通常这不是我们想要的。因此,必须使用 WHERE 子句指定联结条件,过滤出匹配的行。
联结的类型
内联结(INNER JOIN)
返回两个表中满足联结条件的行。是最常用的联结类型。
-- 使用 INNER JOIN 语法
SELECT *
FROM Vendors
INNER JOIN Products ON Vendors.vend_id = Products.vend_id;
-- 等价于隐式内联结(逗号 + WHERE)
SELECT *
FROM Vendors, Products
WHERE Vendors.vend_id = Products.vend_id;
自联结(SELF JOIN)
将同一个表视为两个不同的表进行联结,常用于替代子查询。
示例:查找与 Jim Jones 同一公司的客户。
SELECT c1.cust_id, c1.cust_name, c1.cust_contact
FROM Customers c1
INNER JOIN Customers c2 ON c1.cust_name = c2.cust_name
WHERE c2.cust_contact = 'Jim Jones';
自然联结(NATURAL JOIN)
自然联结会自动排除重复的列,使每一列只出现一次。多数 DBMS 会自动完成,但实际使用中常显式指定列以避免歧义。
SELECT C.*, O.order_num, O.order_date
FROM Customers C
INNER JOIN Orders O ON C.cust_id = O.cust_id
INNER JOIN OrderItems OI ON O.order_num = OI.order_num
WHERE OI.prod_id = 'RGAN01';
外联结(OUTER JOIN)
不仅返回匹配的行,还返回左表或右表中不匹配的行。
- LEFT OUTER JOIN:返回左表所有行,右表无匹配则用 NULL 填充。
- RIGHT OUTER JOIN:返回右表所有行,左表无匹配则用 NULL 填充。
- FULL OUTER JOIN:返回左右表所有行,无匹配则填充 NULL(部分 DBMS 支持)。
-- 左外联结:返回所有客户及其订单号(即使没有订单)
SELECT Customers.cust_id, Orders.order_num
FROM Customers
LEFT OUTER JOIN Orders ON Customers.cust_id = Orders.cust_id;
叉联结(CROSS JOIN)
有时,返回笛卡尔积,即两个表的每一行相互组合。很少直接使用。
SELECT * FROM Vendors CROSS JOIN Products;

联结多个表
SQL 不限制联结的表数,但联结越多,性能开销越大。
SELECT *
FROM OrderItems, Products, Vendors
WHERE Products.vend_id = Vendors.vend_id
AND OrderItems.prod_id = Products.prod_id
AND order_num = 20007;
联结与聚集函数
聚集函数(如 COUNT、SUM)可与联结结合使用,进行分组统计。
示例:统计每个客户的订单数。
SELECT Customers.cust_id, COUNT(Orders.order_num) AS num_ord
FROM Customers
LEFT OUTER JOIN Orders ON Customers.cust_id = Orders.cust_id
GROUP BY Customers.cust_id;
性能注意事项
- 联结操作会消耗数据库资源,表越多、数据量越大,性能下降越明显。
- 尽量避免不必要的联结。
- 确保联结条件正确,否则可能返回笛卡尔积或错误数据。
- 测试复杂联结时,可先分别验证每个子查询的正确性。
联结语法总结
| 联结类型 | 关键字 | 说明 |
|---|---|---|
| 内联结 | INNER JOIN 或 , + WHERE |
仅返回匹配的行 |
| 左外联结 | LEFT OUTER JOIN |
返回左表所有行,右表无匹配补 NULL |
| 右外联结 | RIGHT OUTER JOIN |
返回右表所有行,左表无匹配补 NULL |
| 全外联结 | FULL OUTER JOIN |
返回所有行,无匹配补 NULL |
| 自联结 | 同一表用不同别名联结 | 用于同一张表内的关联查询 |
| 自然联结 | NATURAL JOIN |
自动按同名列联结(不常用) |
| 叉联结 | CROSS JOIN |
返回笛卡尔积 |
注意:不同数据库对联结语法的支持略有差异,请参考相应文档。

浙公网安备 33010602011771号