在本教學中,您將學習到Oracle中的內聯視圖,以及如何使用它們來簡化複雜的查詢或將幾個單獨的查詢合併為一個。
Oracle中的內聯視圖介紹
內聯視圖不是真實的視圖,而是SELECT
語句的FROM
子句中的子查詢。 考慮下麵的SELECT
語句:
SELECT
column_list
FROM
table;
在FROM
子句中,可以指定要查詢數據的表。 除了表格之外,還可以使用如下例所示的子查詢:
SELECT
column_list
FROM
(
SELECT
*
FROM
table_name
) t;
在查詢的FROM
子句中指定的子查詢稱為內聯視圖。 由於內聯視圖可以替換查詢中的表,因此也稱為派生表。 有時,您可能會聽到過“子選擇”這個詞,它與內聯視圖的含義相同。
我們經常使用Oracle中的內聯視圖,通過消除聯接操作或將單獨的查詢集中到單個查詢中來簡化複雜的查詢。
Oracle內聯視圖示例
我們使用示例資料庫中的products
表進行演示。
1. 簡單的Oracle內聯視圖示例
以下查詢將從products
表中檢索前十個價格最高的產品:
SELECT
*
FROM
(
SELECT
product_id,
product_name,
list_price
FROM
products
ORDER BY
list_price DESC
)
WHERE
ROWNUM <= 10;
執行上面查詢語句,得到以下結果 -
在此示例中,首先,內聯視圖按按價格降序排序返回所有產品。 然後,外部查詢從內聯視圖中檢索前10
行。
2. 內聯視圖連接一個表示例
以下示例將內聯視圖與FROM子句中的表連接起來。 它返回每個類別中產品類別和產品的最高價格:
SELECT
category_name,
max_list_price
FROM
product_categories a,
(
SELECT
category_id,
MAX( list_price ) max_list_price
FROM
products
GROUP BY
category_id
) b
WHERE
a.category_id = b.category_id
ORDER BY
category_name;
執行上面查詢語句,得到以下結果 -
在此示例中,內嵌視圖返回每個類別中產品的類別標識列表和最高價格。 外部查詢將內聯視圖與product_categories
表聯合以獲取類別名稱。
3. LATERAL聯視圖示例
考慮以下語句:
SELECT
category_name,
product_name
FROM
products p,
(
SELECT
*
FROM
product_categories c
WHERE
c.category_id = p.category_id
)
ORDER BY
product_name;
Oracle發出了一個錯誤:
ORA-00904: "P"."CATEGORY_ID": invalid identifier
這是因為內聯視圖不能從其定義的外部引用表。
幸運的是,從Oracle 12c開始,通過使用LATERAL
關鍵字,內聯視圖可以引用FROM
子句中內聯視圖定義左表,如以下示例所示:
SELECT
product_name,
category_name
FROM
products p,
LATERAL(
SELECT
*
FROM
product_categories c
WHERE
c.category_id = p.category_id
)
ORDER BY
product_name;
執行上面查詢語句,得到以下結果 -
請注意,LATERAL
內聯視圖受到文檔中列出的一些限制。
4. Oracle內聯視圖:數據操作示例
可以針對可更新的內聯視圖發出數據操作語句(如INSERT
,UPDATE
和DELETE
)。
例如,以下語句將CPU產品的價格提高15%
:
UPDATE
(
SELECT
list_price
FROM
products
INNER JOIN product_categories using (category_id)
WHERE
category_name = 'CPU'
)
SET
list_price = list_price * 1.15;
以下示例刪除價格低於1,000
的所有顯卡:
DELETE
(
SELECT
list_price
FROM
products
INNER JOIN product_categories
USING(category_id)
WHERE
category_name = 'Video Card'
)
WHERE
list_price < 1000;
在本教學中,您已經瞭解了Oracle中的內聯視圖,以簡化複雜的查詢並將幾個單獨的查詢壓縮為一個查詢。