SQL Views
SQL 视图
Section titled “SQL 视图”SQL 视图是根据查询结果定义的虚拟表。可以将其视为一个存储的查询,您可以像与普通表一样与其进行交互。视图本身不存储数据(除非是物化视图,这是一个更高级的主题);相反,当查询视图时,它们会从一个或多个底层基础表中动态检索和呈现数据。
本章解释如何创建、使用、更新定义和删除视图。
SQL CREATE VIEW 语句
Section titled “SQL CREATE VIEW 语句”视图包含行和列,就像真实的表一样。视图中的字段源自数据库中一个或多个基础表中的字段。
使用视图的主要优点:
- 简化性: 简化复杂的查询。用户可以查询视图,而无需了解底层表的结构或连接条件。
- 安全性: 通过只向用户暴露特定列或行来限制数据访问,隐藏敏感信息。
- 逻辑数据独立性: 如果底层表结构发生变化(例如,列重命名或拆分),有时可以修改视图定义以保持应用程序的接口一致,最大程度减少代码修改。
- 可重用性: 只需定义一次通用的数据表示,即可在多个查询或应用程序中使用。
SQL CREATE VIEW 语法
Section titled “SQL CREATE VIEW 语法”CREATE VIEW view_name AS SELECT column1, column2, … FROM table_name [WHERE condition] [GROUP BY …] [HAVING …] [ORDER BY …];
view_name: 您为视图指定的名称。
SELECT ...: 定义视图将呈现数据的标准 SQL SELECT 语句。它可以包含连接、函数、聚合等。
注意:视图始终反映其底层表中的当前数据。每次查询视图时,数据库引擎都会重新执行视图的 SQL 查询(除非它是物化视图)。
SQL CREATE VIEW 示例
Section titled “SQL CREATE VIEW 示例”假设我们有 Products 表和 Categories 表。
Products Table:
- ProductID (INT)
- ProductName (VARCHAR)
- CategoryID (INT)
- UnitPrice (DECIMAL)
- Discontinued (BOOLEAN)
Categories Table:
- CategoryID (INT)
- CategoryName (VARCHAR)
示例 1:活跃产品视图
此视图列出所有未停产的产品。
CREATE VIEW ActiveProducts AS SELECT ProductID, ProductName, UnitPrice, CategoryID FROM Products WHERE Discontinued = FALSE; — Standard SQL for boolean false — 标准 SQL 布尔值 false
然后您可以像查询表一样查询此视图:
SELECT * FROM ActiveProducts WHERE UnitPrice > 50;
示例 2:带有类别名称的产品详情视图
此视图连接 Products 和 Categories 表,以显示产品名称及其对应的类别名称。
CREATE VIEW ProductDetailsWithCategory AS SELECT p.ProductID, p.ProductName, c.CategoryName, p.UnitPrice FROM Products p JOIN Categories c ON p.CategoryID = c.CategoryID;
查询该视图:
SELECT * FROM ProductDetailsWithCategory WHERE CategoryName = ‘Electronics’;
示例 3:类别销售摘要视图(概念性示例)
假设存在一个 OrderDetails 表,此视图可以按类别汇总总销售额。
— This is a conceptual example; OrderDetails table structure is assumed. — 这是一个概念性示例;假设存在 OrderDetails 表结构。 CREATE VIEW CategorySalesSummary AS SELECT c.CategoryName, SUM(od.Quantity * od.UnitPrice) AS TotalSales FROM Categories c JOIN Products p ON c.CategoryID = p.CategoryID JOIN OrderDetails od ON p.ProductID = od.ProductID — Assuming OrderDetails table — 假设存在 OrderDetails 表 GROUP BY c.CategoryName;
查询该视图:
SELECT * FROM CategorySalesSummary ORDER BY TotalSales DESC;
更新视图的定义(CREATE OR REPLACE VIEW)
Section titled “更新视图的定义(CREATE OR REPLACE VIEW)”要修改现有视图的定义,而无需丢弃(drop)并重新创建它(这可能会影响权限),请使用 CREATE OR REPLACE VIEW。
SQL CREATE OR REPLACE VIEW 语法
Section titled “SQL CREATE OR REPLACE VIEW 语法”CREATE OR REPLACE VIEW view_name AS SELECT column_name(s) FROM table_name WHERE condition …
示例:将 Discontinued 状态添加到 ActiveProducts 视图(尽管其名称暗示活跃,但我们可以使其更明确或更改其目的)。或者,更新 ProductDetailsWithCategory 以包含 Discontinued 状态。
CREATE OR REPLACE VIEW ProductDetailsWithCategory AS SELECT p.ProductID, p.ProductName, c.CategoryName, p.UnitPrice, p.Discontinued FROM Products p JOIN Categories c ON p.CategoryID = c.CategoryID;
视图的可更新性(数据修改)
Section titled “视图的可更新性(数据修改)”有时可以使用 INSERT、UPDATE 或 DELETE 语句在视图上修改底层基础表中的数据。但是,只有当数据库能够明确确定哪些基础表行和列受到影响时,视图才是可更新的。通常,如果视图满足以下条件,则是可更新的:
- 基于单个表(或多个表,但 DML 操作仅影响一个基础表)。
- 不使用聚合函数(
SUM()、COUNT()等)。 - 不使用
GROUP BY或HAVING子句。 - 不使用
DISTINCT。 - 在
SELECT列表中不使用引用与FROM子句中相同表的子查询。 - 基础表中所有没有默认值的
NOT NULL列都包含在视图中并且可访问。
确切的规则可能因数据库系统而异。尝试更新不可更新的视图将导致错误。
要从数据库中移除视图,请使用 DROP VIEW 命令。
SQL DROP VIEW 语法
Section titled “SQL DROP VIEW 语法”DROP VIEW view_name;
示例:
DROP VIEW ActiveProducts;
丢弃视图不会影响底层表中的数据。
实际应用场景:
- 为报告仪表板创建
CustomerOrderSummary视图。 - 提供
PublicUserProfile视图,隐藏敏感用户数据,如电子邮件或密码哈希。 - 为定向营销活动构建
HighValueProducts视图。