MySQL創建視圖

在本教學中,您將學習如何使用CREATE VIEW語句在MySQL中創建視圖。

CREATE VIEW語句簡介

要在MySQL中創建一個新視圖,可以使用CREATE VIEW語句。 在MySQL中創建視圖的語法如下:

CREATE
   [ALGORITHM = {MERGE  | TEMPTABLE | UNDEFINED}]
VIEW [database_name].[view_name]
AS
[SELECT  statement]

下麵我們來詳細的查看上面的語法。

查看處理演算法

演算法屬性允許您控制MySQL在創建視圖時使用的機制,MySQL提供了三種演算法:MERGETEMPTABLEUNDEFINED

  • 使用MERGE演算法,MySQL首先將輸入查詢與定義視圖的SELECT語句組合成單個查詢。 然後MySQL執行組合查詢返回結果集。 如果SELECT語句包含集合函數(如MINMAXSUMCOUNTAVG等)或DISTINCTGROUP BYHAVINGLIMITUNIONUNION ALL子查詢,則不允許使用MERGE演算法。 如果SELECT語句無引用表,則也不允許使用MERGE演算法。 如果不允許MERGE演算法,MySQL將演算法更改為UNDEFINED。請注意,將視圖定義中的輸入查詢和查詢組合成一個查詢稱為視圖解析度

  • 使用TEMPTABLE演算法,MySQL首先根據定義視圖的SELECT語句創建一個臨時表,然後針對該臨時表執行輸入查詢。因為MySQL必須創建臨時表來存儲結果集並將數據從基表移動到臨時表,所以TEMPTABLE演算法的效率比MERGE演算法效率低。 另外,使用TEMPTABLE演算法的視圖是不可更新的。

  • 當您創建視圖而不指定顯式演算法時,UNDEFINED是默認演算法。 UNDEFINED演算法使MySQL可以選擇使用MERGETEMPTABLE演算法。MySQL優先使用MERGE演算法進行TEMPTABLE演算法,因為MERGE演算法效率更高。

查看名稱

在資料庫中,視圖和表共用相同的命名空間,因此視圖和表不能具有相同的名稱。 另外,視圖的名稱必須遵循表的命名規則。

SELECT語句

SELECT語句中,可以從資料庫中存在的任何表或視圖查詢數據。SELECT語句必須遵循以下幾個規則:

  • SELECT語句可以在WHERE子句中包含子查詢,但FROM子句中的不能包含子查詢。
  • SELECT語句不能引用任何變數,包括局部變數,用戶變數和會話變數。
  • SELECT語句不能引用準備語句的參數。

請注意,SELECT語句不需要引用任何表。

創建MySQL視圖示例

創建簡單的視圖

我們來看看orderDetails表。基於orderDetails表來創建一個表示每個訂單的總銷售額的視圖。

CREATE VIEW SalePerOrder AS
    SELECT
        orderNumber, SUM(quantityOrdered * priceEach) total
    FROM
        orderDetails
    GROUP by orderNumber
    ORDER BY total DESC;

如果使用SHOW TABLES命令來查看示例資料庫(zaixiandb)中的所有表,我們還會看到SalesPerOrder視圖也顯示在表的列表中。如下所示 -

mysql> SHOW TABLES;
+--------------------+
| Tables_in_zaixiandb |
+--------------------+
| article_tags       |
| contacts           |
| customers          |
| departments        |
| employees          |
| offices            |
| offices_bk         |
| offices_usa        |
| orderdetails       |
| orders             |
| payments           |
| productlines       |
| products           |
| saleperorder       |
+--------------------+
14 rows in set

這是因為視圖和表共用相同的命名空間。要知道哪個對象是視圖或表,請使用SHOW FULL TABLES命令,如下所示:

mysql> SHOW FULL TABLES;
+--------------------+------------+
| Tables_in_zaixiandb | 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       |
+--------------------+------------+
14 rows in set

結果集中的table_type列指定哪個對象是視圖,哪個對象是一個表(基表)。如上所示,saleperorder對應table_type列的值為:VIEW

如果要查詢每個銷售訂單的總銷售額,只需要對SalePerOrder視圖執行一個簡單的SELECT語句,如下所示:

SELECT
    *
FROM
    salePerOrder;

執行上面查詢語句,得到以下結果 -

+-------------+----------+
| orderNumber | total    |
+-------------+----------+
|       10165 | 67392.85 |
|       10287 | 61402.00 |
|       10310 | 61234.67 |
|       10212 | 59830.55 |
|-- 此處省略了一大波數據-- |
|       10116 | 1627.56  |
|       10158 | 1491.38  |
|       10144 | 1128.20  |
|       10408 | 615.45   |
+-------------+----------+
327 rows in set

基於另一個視圖創建視圖

MySQL允許您基於另一個視圖創建一個視圖。例如,可以根據SalesPerOrder視圖創建名為大銷售訂單(BigSalesOrder)的視圖,以顯示總計大於60,000的每個銷售訂單,如下所示:

CREATE VIEW BigSalesOrder AS
    SELECT
        orderNumber, ROUND(total,2) as total
    FROM
        saleperorder
    WHERE
        total > 60000;

現在,我們可以從BigSalesOrder視圖查詢數據,如下所示:

SELECT
    orderNumber, total
FROM
    BigSalesOrder;

執行上面查詢語句,得到以下結果 -

+-------------+----------+
| orderNumber | total    |
+-------------+----------+
|       10165 | 67392.85 |
|       10287 | 61402.00 |
|       10310 | 61234.67 |
+-------------+----------+
3 rows in set

使用連接表創建視圖

以下是使用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;

要查詢customerOrders視圖中的數據,請使用以下查詢:

SELECT  * FROM customerOrders;

執行上面查詢語句,得到以下結果 -

+----------------+-----------+
| customerNumber | amount    |
+----------------+-----------+
|            124 | 101244.59 |
|            321 | 85559.12  |
|            239 | 80375.24  |
| **** 此處省略了一大波數據 ***|
|            219 | 3452.75   |
|            216 | 3101.4    |
|            161 | 2434.25   |
|            172 | 1960.8    |
+----------------+-----------+
98 rows in set

使用子查詢創建視圖

以下說明如何使用子查詢創建視圖,該視圖包含價格高於所有產品的平均價格的產品。

CREATE VIEW aboveAvgProducts AS
    SELECT
        productCode, productName, buyPrice
    FROM
        products
    WHERE
        buyPrice >
 (SELECT
                AVG(buyPrice)
            FROM
                products)
    ORDER BY buyPrice DESC;

查詢上述視圖:aboveAvgProducts的數據簡單如下:

SELECT
    *
FROM
    aboveAvgProducts;

執行上面查詢語句,得到以下結果 -

+-------------+-----------------------------------------+----------+
| productCode | productName                             | buyPrice |
+-------------+-----------------------------------------+----------+
| S10_4962    | 1962 LanciaA Delta 16V                  | 103.42   |
| S18_2238    | 1998 Chrysler Plymouth Prowler          | 101.51   |
| S10_1949    | 1952 Alpine Renault 1300                | 98.58    |
|************* 此處省略了一大波數據 *********************************|
| S18_3320    | 1917 Maxwell Touring Car                | 57.54    |
| S24_4258    | 1936 Chrysler Airflow                   | 57.46    |
| S18_3233    | 1985 Toyota Supra                       | 57.01    |
| S18_2870    | 1999 Indy 500 Monte Carlo SS            | 56.76    |
| S32_4485    | 1974 Ducati 350 Mk3 Desmo               | 56.13    |
| S12_4473    | 1957 Chevy Pickup                       | 55.7     |
| S700_3167   | F/A 18 Hornet 1/72                      | 54.4     |
+-------------+-----------------------------------------+----------+
54 rows in set

在本教學中,我們向您展示了如何使用CREATE VIEW語句創建視圖。


上一篇: MySQL視圖 下一篇: MySQL觸發器