在本教學中,您將學習到Oracle中的內聯檢視,以及如何使用它們來簡化複雜的查詢或將幾個單獨的查詢合併為一個。
內聯檢視不是真實的檢視,而是SELECT
語句的FROM
子句中的子查詢。 考慮下面的SELECT
語句:
SELECT
column_list
FROM
table;
在FROM
子句中,可以指定要查詢資料的表。 除了表格之外,還可以使用如下例所示的子查詢:
SELECT
column_list
FROM
(
SELECT
*
FROM
table_name
) t;
在查詢的FROM
子句中指定的子查詢稱為內聯檢視。 由於內聯檢視可以替換查詢中的表,因此也稱為派生表。 有時,您可能會聽到過「子選擇」這個詞,它與內聯檢視的含義相同。
我們經常使用Oracle中的內聯檢視,通過消除聯接操作或將單獨的查詢集中到單個查詢中來簡化複雜的查詢。
我們使用範例資料庫中的products
表進行演示。
以下查詢將從products
表中檢索前十個價格最高的產品:
SELECT
*
FROM
(
SELECT
product_id,
product_name,
list_price
FROM
products
ORDER BY
list_price DESC
)
WHERE
ROWNUM <= 10;
執行上面查詢語句,得到以下結果 -
在此範例中,首先,內聯檢視按按價格降序排序返回所有產品。 然後,外部查詢從內聯檢視中檢索前10
行。
以下範例將內聯檢視與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
表聯合以獲取類別名稱。
考慮以下語句:
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
內聯檢視受到文件中列出的一些限制。
可以針對可更新的內聯檢視發出資料操作語句(如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中的內聯檢視,以簡化複雜的查詢並將幾個單獨的查詢壓縮為一個查詢。