在本教程中,您将学习到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中的内联视图,以简化复杂的查询并将几个单独的查询压缩为一个查询。