本學習筆記參考《MySQL必知必會》和官方手冊MySQL 5.6 Reference Manual
MySQL入門(一)
MySQL入門(三)
本文內容:
- MySQL聯結表
- MySQL視圖
假設要存儲貨物的信息,建立一個 products 表,每種貨物的信息占一行,包括產品名字,產地以及供應商的信息(供應商名字,電話等)。同一個供應商可能有多種產品,那麼這時屬於同一供應商的不同產品可能要重復存儲供應商的信息,這會造成存儲空間和時間的浪費,改動的不方便等。解決這個問題的方法是建立兩個表,products 和 vendors ,vendors 表中以供應商ID(vend_id)作為主鍵(primary key),products 表中以 vend_id 作為外鍵(foreign key),這樣兩個表之間就建立了聯系。
如果數據存儲在多個表中可以使用聯結來查詢,聯結是一種機制,用來在一條 SELECT 語句中關聯表。
一個聯結的例子(利用 WHERE 實現):
mysql> SELECT vend_name, prod_name, prod_price
-> FROM vendors, products
-> WHERE vendors.vend_id = products.vend_id
-> ORDER BY vend_name, prod_name;
由沒有聯結條件的表關系返回的結果為笛卡爾積,檢索出的行數目是第一個表中的行數乘以第二個表中的行數。
目前為止所用的聯結稱為等值聯結(equijoin),它基於兩個表之間的相等測試,這種聯結也成為內部聯結。下面更為規范和首選的方法和上面的寫法返回相同的結果。
mysql> SELECT vend_name, prod_name, prod_price
-> FROM vendors INNER JOIN products
-> ON vendors.vend_id = products.vend_id;
mysql> SELECT prod_name, vend_name, prod_price, quantity
-> FROM orderitems, products, vendors
-> WHERE products.vend_id = vendors.vend_id
-> AND orderitems.prod_id = products.prod_id
-> AND order_num = 20005;
為簡便起見也可以使用表別名來進行查詢,表別名和列別名不一樣,表別名不返回到客戶機。下面的語句使用表別名,和上面的語句返回相同的結果。
mysql> SELECT prod_name, vend_name, prod_price, quantity
-> FROM orderitems AS o, products AS p, vendors AS v
-> WHERE p.vend_id = v.vend_id
-> AND o.prod_id = p.prod_id
-> AND o.order_num = 20005;
假如你發現某物品(其ID為DTNTR)存在問題,因此你想知道生產該物品的供應商生產的其他物品是否也存在這些問題。此查詢要求首先找到生產ID為DTNTR的物品的供應商,然後找出這個供應商生產的其他物品。
用子查詢的方式:
mysql> SELECT vend_id, prod_id, prod_name
-> FROM products
-> WHERE vend_id IN ( SELECT vend_id
-> FROM products
-> WHERE prod_id = 'DTNTR' );
customers 表存儲所有客戶的信息,每個客戶有唯一的ID(cust_id),cust_id 為 customers 的主鍵。orders 表存儲客戶訂單(但不是訂單細節),每個訂單有唯一的訂單號(order_num),訂單用 cust_id 列與 customers 表關聯。 查詢存在訂單的客戶及其訂單號(可以用內聯結): 一篇介紹聯結的文章 視圖是虛擬的表。與包含數據的表不一樣,視圖只包含使用時動態檢索數據的查詢。 寫出這樣的語句必須知道表的結構和聯結關系,現在如果把這個查詢包裝成一個名為 productcustomers 的虛擬表,則可以如下輕松的檢索出相同的數據: 重用SQL語句;簡化復雜的SQL操作;保護數據。但由於視圖不包含數據,每次使用時都要完成一個檢索,所以會影響性能。 用 CREATE VIEW 語句來創建視圖; 上面的語句創建了一個名為 productcustomers 的視圖,它聯結三個表,以返回訂購了任意產品的所有客戶列表。 新建視圖 customeremaillist 過濾沒有郵箱地址的用戶。 新建一個視圖 orderitemsexpanded ,計算出所有訂單裡產品的總價格。 利用 DESCRIBE 語句查看視圖的基本信息: 查看所有已創建視圖的信息:
用自聯結的方式:<喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KCgoKPHByZSBjbGFzcz0="brush:sql;">mysql> SELECT p1.vend_id, 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';
4.4 外部聯結
mysql> SELECT customers.cust_id, cust_name, orders.order_num
-> FROM customers INNER JOIN orders
-> ON customers.cust_id = orders.cust_id;
查詢所有客戶及其訂單(包括沒有訂單的客戶):mysql> SELECT customers.cust_id, cust_name, orders.order_num
-> FROM customers LEFT OUTER JOIN orders
-> ON customers.cust_id = orders.cust_id;
在使用 OUTER JOIN 語法時,必須使用 LEFT 或 RIGHT 關鍵字指定包括其所有行的表(RIGHT 指的是 OUTER JOIN 右邊的表,LEFT 指的是 OUTER JOIN 左邊的表)。4.5 使用帶聚集函數的聯結
mysql> SELECT customers.cust_id, cust_name, orders.order_num,
-> COUNT(orders.order_num) AS num_ord
-> FROM customers INNER JOIN orders
-> ON customers.cust_id = orders.cust_id
-> GROUP BY customers.cust_id;
五、MySQL視圖
5.1 什麼是視圖
例子,下面的語句完成檢索訂購了某個特定產品的客戶的信息。mysql> SELECT cust_name, cust_contact
-> FROM customers, orders, orderitems
-> WHERE customers.cust_id = orders.cust_id
-> AND orders.order_num = orderitems.order_num
-> AND orderitems.prod_id = 'TNT2';
mysql> SELECT cust_name, cust_contact
-> FROM productcustomers
-> WHERE prod_id = 'TNT2';
5.2 為什麼使用視圖
5.3 使用視圖
用 SHOW CREATE VIEW viewname; 語句來查看創建該視圖的語句;
用 DROP VIEW viewname; 來刪除視圖;
更新視圖時,可以先用 DROP 在用 CREATE。也可以直接用 CREATE OR REPLACE VIEW,如果視圖不存在則創建,如果存在則替換原視圖。(1) 利用視圖簡化復雜的聯結
mysql> CREATE VIEW productcustomers AS
-> SELECT cust_name, cust_contact, prod_id
-> FROM customers, orders, orderitems
-> WHERE customer.cust_id = orders.cust_id
-> AND orders.order_num = orderitems.order_num;
mysql> SELECT * FROM productcustomers;
(2) 用視圖重新格式化檢索出來的數據
mysql> CREATE VIEW vendorlocations AS
-> SELECT Concat(RTrim(vend_name), ' (', RTrim(vend_country), ')')
-> AS vend_title
-> FROM vendors ORDER BY vend_name;
mysql> SELECT * FROM vendorlocations;
(3) 用視圖過濾不想要的數據
mysql> CREATE VIEW customeremaillist AS
-> SELECT cust_id, cust_name, cust_email
-> FROM customers
-> WHERE cust_email IS NOT NULL;
mysql> SELECT * FROM customeremaillist;
(4) 使用視圖與計算字段
mysql> CREATE VIEW orderitemsexpanded AS
-> SELECT order_num, prod_id, quantity, item_price,
-> quantity * item_price AS expanded_price
-> FROM orderitems;
mysql> SELECT * FROM orderitemsexpanded
-> WHERE order_num = 20005;
5.4 查看視圖的信息
mysql> DESC orderitemsexpanded;
mysql> SHOW CREATE VIEW orderitemsexpanded;
mysql> USE information_schema;
mysql> SELECT * FROM views; // 該語句輸出信息比較多
mysql> SELECT TABLE_NAME, DEFINER FROM views;