一、联结概述
-
联结(JOIN)就是将其他表中的列添加过来,进行“添加列”的集合运算。UNION是以行(纵向)为单位进行操作,而联结则是以列(横向)为单位进行的
-
联结大体上分为内联结和外联结两种。
联结图示:
准备联结示例所需的两张表(product表和shop表),如下:
对这两张表包含的列进行整理后的结果如下表所示:
Product(产品) | Shop(商店) | |
---|---|---|
product_id | 存在 | 存在 |
product_name | 存在 | |
product_price | 存在 | |
shop_id | 存在 | |
shop_name | 存在 | |
product_nums | 存在 |
如上表所示,两张表中的列可以分为如下两类:
- A.两张表中都包含的列 → 商品编号
- B.只存在于一张表内的列 → 商品编号之外的列
所谓联结运算,一言以蔽之,就是“以A中的列作为桥梁,将 B中满足同样条件的列汇集到同一结果之中”。
二、内联结
- 内联结也称为等值联结,返回两张表都满足条件的部分
-- inner join可以简化,直接写成join
SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name,P.sale_price
FROM Shop AS SP INNER JOIN Product AS P
ON SP.product_id = P.product_id;
注意:
-
为表取别名不是必须的,但是为了可读性更好,建议这么做
-
ON 之后指定两张表联结所使用的列(联结键),需要指定多个键时,同样可以使用 AND、OR
- 内联结和WHERE等子句结合使用
使用联结运算除了表与表之间的桥梁条件需要放在on后,其他的条件可以使用WHERE、GROUP BY、HAVING、ORDER BY 等字句来添加
-- 查询内联结结果中shop_id为00A的信息
SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name,P.sale_price
FROM Shop AS SP INNER JOIN Product AS P
ON SP.product_id = P.product_id
WHERE SP.shop_id = "00A";
3. 内联结的另一种写法(过时语法)
-- 内联结另一种写法
SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name,P.sale_price
FROM Shop AS SP , Product AS P
WHERE SP.product_id = P.product_id;
这种写法与使用inner join… on…写法得到的结果一模一样,但是这是一种未来会被淘汰的写法,即过时的语法,其除了未来可能被淘汰,还有以下几个缺点:
- 由于联结条件都写在 WHERE 子句之中,因此无法在短时间内分辨出哪部分是联结条件,哪部分是用来选取记录的限制条件
- 我们不知道这样的语法到底还能使用多久。每个 DBMS 的开发者都会考虑放弃过时的语法,转而支持新的语法。虽然并不是马上就不能使用了,但那一天总会到来的
三、外联结
外联结也是通过 ON 子句的联结键将两张表进行联结,但是不同的是,外联结分主表和从表,在内联结里,是将两表可以联结的数据列出来,但是外联结会把主表中的数据全部列出来,如果从表中没有对应的数据,就设置为null。
简而言之,就是外联结可以查出null的数据,而内联结不行
/*
将内联结的inner join
改为right join就是右联结,
改为left join就是左联结
*/
SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name,P.sale_price
FROM Shop AS SP RIGHT JOIN Product AS P
ON SP.product_id = P.product_id
这里使用right join即右联结,所以Product为主表,由查询结果可知,它不仅将两表通过on条件联结的部分查询出来(和二表做内联结一模一样),它还将主表(Product)中未与从表(Shop)关联的部分单独列了两行出来,从表中数据赋NULL