要在MySQL中創建一個新視圖,可以使用CREATE VIEW
語句。 在MySQL中創建視圖的語法如下:
CREATE [ALGORITHM = {MERGE | TEMPTABLE | UNDEFINED}] VIEW [database_name].[view_name] AS [SELECT statement]
1、查看處理算法
算法屬性允許您控制MySQL在創建視圖時使用的機制,MySQL提供了三種算法:MERGE
,TEMPTABLE
和 UNDEFINED
。
-
使用
MERGE
算法,MySQL首先將輸入查詢與定義視圖的SELECT語句組合成單個查詢。 然后MySQL執行組合查詢返回結果集。 如果SELECT語句包含集合函數(如MIN,MAX,SUM,COUNT,AVG等)或DISTINCT,GROUP BY,HAVING,LIMIT,UNION,UNION ALL,子查詢,則不允許使用MERGE
算法。 如果SELECT語句無引用表,則也不允許使用MERGE
算法。 如果不允許MERGE
算法,MySQL將算法更改為UNDEFINED
。請注意,將視圖定義中的輸入查詢和查詢組合成一個查詢稱為視圖分辨率。
- 使用
TEMPTABLE
算法,MySQL首先根據定義視圖的SELECT
語句創建一個臨時表,然后針對該臨時表執行輸入查詢。因為MySQL必須創建臨時表來存儲結果集並將數據從基表移動到臨時表,所以TEMPTABLE
算法的效率比MERGE
算法效率低。 另外,使用TEMPTABLE
算法的視圖是不可更新的。
-
當您創建視圖而不指定顯式算法時,
UNDEFINED
是默認算法。UNDEFINED
算法使MySQL可以選擇使用MERGE
或TEMPTABLE
算法。MySQL優先使用MERGE
算法進行TEMPTABLE
算法,因為MERGE
算法效率更高。
2、查看名稱
在數據庫中,視圖和表共享相同的命名空間,因此視圖和表不能具有相同的名稱。 另外,視圖的名稱必須遵循表的命名規則。
SELECT語句
在SELECT
語句中,可以從數據庫中存在的任何表或視圖查詢數據。SELECT
語句必須遵循以下幾個規則:
SELECT
語句可以在WHERE子句中包含子查詢,但FROM
子句中的不能包含子查詢。SELECT
語句不能引用任何變量,包括局部變量,用戶變量和會話變量。SELECT
語句不能引用准備語句的參數。
請注意,
SELECT
語句不需要引用任何表。
3、創建MySQL視圖示例
創建簡單的視圖
我們來看看orderDetails
表。基於orderDetails
表來創建一個表示每個訂單的總銷售額的視圖。
CREATE VIEW SalePerOrder AS SELECT orderNumber, SUM(quantityOrdered * priceEach) total FROM orderDetails GROUP by orderNumber ORDER BY total DESC;
要知道哪個對象是視圖或表,請使用SHOW FULL TABLES
命令,如下所示:
mysql> SHOW FULL TABLES; +--------------------+------------+ | Tables_in_yiibaidb | Table_type | +--------------------+------------+ | article_tags | BASE TABLE | | contacts | BASE TABLE | | customers | BASE TABLE | | departments | BASE TABLE | | employees | BASE TABLE | | offices | BASE TABLE | | offices_bk | BASE TABLE | | offices_usa | BASE TABLE | | orderdetails | BASE TABLE | | orders | BASE TABLE | | payments | BASE TABLE | | productlines | BASE TABLE | | products | BASE TABLE | | saleperorder | VIEW | +--------------------+------------+
table_type
列指定哪個對象是視圖,哪個對象是一個表(基表)。如上所示,
saleperorder
對應
table_type
列的值為:
VIEW
使用連接表創建視圖
以下是使用INNER JOIN創建視圖的示例。 該視圖包含客戶編號和客戶支付的總金額。
CREATE VIEW customerOrders AS SELECT c.customerNumber, p.amount FROM customers c INNER JOIN payments p ON p.customerNumber = c.customerNumber GROUP BY c.customerNumber ORDER BY p.amount DESC;
使用子查詢創建視圖
CREATE VIEW aboveAvgProducts AS SELECT productCode, productName, buyPrice FROM products WHERE buyPrice > (SELECT AVG(buyPrice) FROM products) ORDER BY buyPrice DESC;