简介
保存数据时往往不会将所有数据保存在一个表中,而是在多个表中存储。
联结表就是从多个表查询数据,其实就是多表操作。
联结(JOIN)是一种机制,用来在一条SELECT 语句中关联表。
优点
- 数据信息不重复,从而不浪费时间和空间。
- 如果某个数据信息变动,可以只更新该表中的某个记录,相关表数据不用变更。
- 更有效的存储和方便的处理,伸缩性强,就是能够适应不断增加的工作量而不失败。
WHERE子句的重要性
在联结两个表时,实际上是将第一个表中的每一行与第二个表中的每一行配对。
where子句作为过滤条件,它只包含那些匹配给定条件(这里是联结条件)的行。
由没有联结条件的表关系返回的结果为笛卡儿积。
笛卡尔积
由没有联结条件的表关系返回的结果为笛卡儿积。
检索出的行的数目 将是第一个表中的行数乘以第二个表中的行数。
表联结
叉联结
有时,返回笛卡儿积的联结,也称叉联结(cross join)
内联结
基于两个表之间的相等测试的等值联接,这种联结也称为内联结(inner join)。
SELECT * FROM Vendors INNER JOIN Products
ON Vendors.vend_id = Products.vend_id;
自联结
通常作为外部语句,用来代替从相同表中检索数据的子查询语句
SELECT cust_id, cust_name, cust_contact
FROM Customers WHERE cust_name =
(SELECT cust_name FROM Customers WHERE cust_contact = 'Jim Jones');
联结多个表
SQL 不限制一条SELECT 语句中可以联结的表的数目
SELECT * FROM OrderItems, Products, Vendors
WHERE Products.vend_id = Vendors.vend_id
AND OrderItems.prod_id = Products.prod_id
AND order_num = 20007;
自然联结
排除相同列多次出现,使每一列只返回一次
事实上,目前为止所用到的每个内联结都是自然联结
SELECT C.*, O.order_num, O.order_date
FROM Customers AS C, Orders AS O, OrderItems AS OI
WHERE C.cust_id = O.cust_id
AND OI.order_num = O.order_num AND prod_id = 'RGAN01';
外联结
外联结包含了那些在相关表中没有关联的行
SELECT Customers.cust_id, Orders.order_num
FROM Customers LEFT OUTER JOIN Orders
ON Customers.cust_id = Orders.cust_id;
使用带聚集函数的联结
聚集函数可以与联结一起使用
SELECT Customers.cust_id, COUNT(Orders.order_num) AS num_ord
FROM Customers INNER JOIN Orders ON Customers.cust_id = Orders.cust_id
GROUP BY Customers.cust_id;
性能考虑
DBMS 在运行时关联指定的每个表,以处理联结
这种处理可能非常耗费资源,因此应该注意,不要联结不必要的表
联结的表越多,性能下降越厉害
使用联结和联结条件
- 注意联结类型,虽然一般情况下都是用内联结
- 不同的DBMS对联结语法的定义不同
- 确保并提供正确的联结条件,否则会返回不正确的数据或笛卡尔积
- 测试包含多个联结的语句前,应该分别测试每个联结