背景: 假若有由同一供應商生產的多種物品,應當分爲多個表存儲: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)
==應該老是提供聯結條件,不然會得出笛卡兒積。==