联结(join)操作是SQL语言最强大的功能之一。这个操作是建立在关系表的基础之上的
1--关系表
何谓关系表?
假设有一个产品表,每一个产品都有自己的属性和供应商,一个供应商可能有多种产品。
那么在何处存储供应商的信息呢?如果直接在产品表里面存储,假设某个供应商有一千种产品,
在产品表里,该供应商的信息就会被存储1000次,供应商要改个名字就要到表里改1000次,
这样不仅速度慢,还容易出错。
关键是,相同数据在表中多次出现不是什么好事(至少很浪费空间)。这时,关系表的作用
就显现出来了。我们可以建立两个表,供应商表和产品表。每个供应商都有一个独一无二的ID,
产品表每个产品里面存储一个供应商ID,两个表就能通过一个ID联系起来,即每个产品都能通过
其供应商ID找到对应的供应商。
供应商的ID就是主键,同时它也是产品表的外键,这个外键将产品表和供应商表关联起来。
这样做的好处有很多:不会产生重复的信息,如果供应商信息变动,只需要修改供应商表里的一条
信息即可。
2--联结(内联结)
以上面的例子说,当我们需要检索出一个产品的属性和它的供应商的属性时,需要两个表的信息
对应联结起来,这时候就用到了联结。
创建联结
SELECT vend_name, prod_name, prod_price FROM vendors, products WHERE vendors.vend_id = products.vend_id
如果没有where子句(即没有联结条件),输出的结果将是两个表的笛卡尔积。输出结果的数目将是第一个
表的行数乘以第二个表的行数。
内部联结
上面例子使用等值联结,也称为内部联结。
SELECT vend_name, prod_name, prod_price FROM vendors INNER JOIN products ON vendors.vend_id = products.vend_id
3--引用完整性
4--联结多个表
显示编号为20005的订单中的物品的基本信息和供应商信息
SELECT prod_name, prod_price, vend_name, quantity FROM orderitems, products, vendors WHERE order_num = 20005 AND orderitems.prod_id = products.prod_id AND products.vend_id = vendors.vend_id
返回订购了TNT2的客户的信息
SELECT customers.cust_name, customers.cust_contact, orderitems.quantity FROM customers, orders, orderitems WHERE orderitems.prod_id = ‘TNT2‘ AND orders.order_num = orderitems.order_num AND customers.cust_id = orders.cust_id
5--使用表的别名
对上一个例子使用别名,可以缩短代码长度,结果相同
SELECT c.cust_name, c.cust_contact, oi.quantity FROM customers AS c, orders AS o, orderitems AS oi WHERE oi.prod_id = ‘TNT2‘ AND o.order_num = oi.order_num AND c.cust_id = o.cust_id
6--自联结
找出某个产品的供应商生产的其他产品
1.使用子查询
SELECT prod_id, prod_name FROM products WHERE vend_id = ( SELECT vend_id FROM products WHERE prod_id = ‘DTNTR‘ )
2.使用自联结
SELECT p1.prod_id, p1.prod_name FROM products AS p1, products AS p2 WHERE p1.vend_id = p2.vend_id AND p2.prod_id = ‘DTNTR‘
7--外部联结
上述例子中,联结包含了那些在相关表中没有关联行的行,这种类型的联结称为外部联结。
检索所有客户及其订单
1.使用内联结
SELECT cust_name, order_num FROM customers AS c INNER JOIN orders AS o ON c.cust_id = o.cust_id
未列出没有订单的顾客
2.使用外联结
SELECT cust_name, order_num FROM customers AS c LEFT OUTER JOIN orders AS o ON c.cust_id = o.cust_id
列出了没有订单的顾客
使用OUTER JOIN语法时,必须指定RIGHT或LEFT关键字
这里LEFT表示列出左边customer表中的所有行
8--使用带聚集函数的联结
检索所有客户和每个客户所下的订单数。
SELECT c.cust_name, c.cust_id, COUNT(o.order_num) AS num_ord FROM customers AS c LEFT OUTER JOIN orders AS o ON c.cust_id = o.cust_id GROUP BY c.cust_id
9--总结