程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> MySQL入門(二)

MySQL入門(二)

編輯:MySQL綜合教程

MySQL入門(二)


本學習筆記參考《MySQL必知必會》和官方手冊MySQL 5.6 Reference Manual

MySQL入門(一)
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;

這裡寫圖片描述
由沒有聯結條件的表關系返回的結果為笛卡爾積,檢索出的行數目是第一個表中的行數乘以第二個表中的行數。

4.1 內部聯結

目前為止所用的聯結稱為等值聯結(equijoin),它基於兩個表之間的相等測試,這種聯結也成為內部聯結。下面更為規范和首選的方法和上面的寫法返回相同的結果。

mysql> SELECT vend_name, prod_name, prod_price
    -> FROM vendors INNER JOIN products
    -> ON vendors.vend_id = products.vend_id;

4.2 聯結多個表

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;

4.3 自聯結

假如你發現某物品(其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' );

這裡寫圖片描述
用自聯結的方式:<喎?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 外部聯結

customers 表存儲所有客戶的信息,每個客戶有唯一的ID(cust_id),cust_id 為 customers 的主鍵。orders 表存儲客戶訂單(但不是訂單細節),每個訂單有唯一的訂單號(order_num),訂單用 cust_id 列與 customers 表關聯。

查詢存在訂單的客戶及其訂單號(可以用內聯結):

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';

寫出這樣的語句必須知道表的結構和聯結關系,現在如果把這個查詢包裝成一個名為 productcustomers 的虛擬表,則可以如下輕松的檢索出相同的數據:

mysql> SELECT cust_name, cust_contact 
    -> FROM productcustomers 
    -> WHERE prod_id = 'TNT2';

5.2 為什麼使用視圖

重用SQL語句;簡化復雜的SQL操作;保護數據。但由於視圖不包含數據,每次使用時都要完成一個檢索,所以會影響性能。

5.3 使用視圖

用 CREATE VIEW 語句來創建視圖;
用 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;

上面的語句創建了一個名為 productcustomers 的視圖,它聯結三個表,以返回訂購了任意產品的所有客戶列表。

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;

新建視圖 customeremaillist 過濾沒有郵箱地址的用戶。

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;

新建一個視圖 orderitemsexpanded ,計算出所有訂單裡產品的總價格。

mysql> SELECT * FROM orderitemsexpanded
    -> WHERE order_num = 20005;

這裡寫圖片描述

5.4 查看視圖的信息

利用 DESCRIBE 語句查看視圖的基本信息:

mysql> DESC orderitemsexpanded;

這裡寫圖片描述

mysql> SHOW CREATE VIEW orderitemsexpanded;

查看所有已創建視圖的信息:

mysql> USE information_schema;
mysql> SELECT * FROM views;            // 該語句輸出信息比較多
mysql> SELECT TABLE_NAME, DEFINER FROM views;

這裡寫圖片描述

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved