背景: 假若有由同一供应商生产的多种物品,应当分为多个表存储:mysql
分为两个表存储:sql
(1) product表存储商品信息和供应商ID。关于供应商的信息除了ID外不在product表中存储其它的。函数
(2) vendors 表包含全部供应商信息,每一个供应商占一行,每一个供应商具备惟一的标识。此标识称为主键。在这里是供应商ID。性能
如今咱们就能够经过product表中的商品得到供应商ID, 而后再vendors表中找到供应商信息。学习
select vend_name,prod_name from vendors,products where vendors.vend_id = products.vend_id;
咱们经过一个where语句来联结两个表。这里咱们的id都用彻底限定,即表名.列名,不然会出现二义性,不知道是哪一个表的字段。测试
where的重要性:
code
如上图所述,咱们进行联结的时候是将第一个表中的每一行与第二个表中的每一行配对。where进行过滤。blog
由没有联结条件的表关系返回的结果为笛卡儿积。检索出的行的数目将是第一个表中的行数乘以第二个表中的行数。ip
上述基于两个表之间的相等测试。这种联结也称为==内部联结==。产品
select vend_name,prod_name,prod_price from vendors inner join products on vendors.vend_id = products.vend_id;
使用 inner join table_name on conditions来联结table_name这个表,限制条件是conditions. 使用on来代替where子句。
也能够联结多个表:
select prod_name,vend_name,prod_price,quantity from orderitems,vendors,products where products.vend_id = vendors.vend_id and ordeeritems.prod_id = products.prod_id and order_num = 20005;
过滤出订单编号为20005的数据。
联结的表越多,性能降低越厉害。
首先说一下表别名。
select cust_name , cust_contact from customers as c,orders as o,orderitems as oi where c.cust_id = o.cust_id and oi.order_num = o.order_.order_num and prod_id = 'TNT2';
如此更便捷。
tips:应该注意,表别名只在查询执行中使用。与列别名不同,==表别名不返回到客户机。==
使用自联结的时候要用到表别名。例子:在一个商品表中,一个商品ID为'DTNTR'的商品有问题,如今要找到它对应生产厂商所生产的全部商品。
咱们分两步来检索:
(1) 经过商品ID在表中检索出厂家ID。
(2) 经过厂家ID检索出全部这个厂家的商品。
若是使用子查询是这样的:
select prod_name,prod_id from products where vend_id = (select vend_id from products where prod_id = 'DTNTR');
可是咱们能够使用自联结:
mysql> select p1.prod_name, p2.prod_id from products as p1, products as p2 -> where p1.prod_id = 'DTNTR' -> and p2.vend_id = p1.vend_id;
注意咱们使用的是p1.prod_name而不是prod_name。
当咱们使用内联结时,找到的都是等值匹配中存在的数据。若咱们要查找用户的订单数量,没有订单的也要显示。
使用内联结:
mysql> select customers.cust_id,orders.order_num -> from customers inner join orders -> on customers.cust_id = orders.cust_id;
输出结果以下:
+---------+-----------+ | cust_id | order_num | +---------+-----------+ | 10001 | 20005 | | 10001 | 20009 | | 10003 | 20006 | | 10004 | 20007 | | 10005 | 20008 | +---------+-----------+ 5 rows in set (0.00 sec)
很明显咱们没有把订单数量为空的cust_id找出来。
这个时候使用==外联结:==
mysql> select customers.cust_id,orders.order_num -> from customers left outer join orders -> on customers.cust_id = orders.cust_id;
输出以下:
+---------+-----------+ | cust_id | order_num | +---------+-----------+ | 10001 | 20005 | | 10001 | 20009 | | 10002 | NULL | | 10003 | 20006 | | 10004 | 20007 | | 10005 | 20008 | +---------+-----------+ 6 rows in set (0.00 sec)
能够看到咱们把order_num为空的一块儿检索出来了。
如今学习一下外联结的语法。
以cust_id为分组,检索customers和orders表中cust_id相同的数据(包括名字,id,和总数)。
mysql> select customers.cust_name,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;
结果为:
+----------------+---------+---------+ | cust_name | cust_id | num_ord | +----------------+---------+---------+ | Coyote Inc. | 10001 | 2 | | Wascals | 10003 | 1 | | Yosemite Place | 10004 | 1 | | E Fudd | 10005 | 1 | +----------------+---------+---------+ 4 rows in set (0.00 sec)
==应该老是提供联结条件,不然会得出笛卡儿积。==