Skip to content

SQL Views

SQL 视图是根据查询结果定义的虚拟表。可以将其视为一个存储的查询,您可以像与普通表一样与其进行交互。视图本身不存储数据(除非是物化视图,这是一个更高级的主题);相反,当查询视图时,它们会从一个或多个底层基础表中动态检索和呈现数据。

本章解释如何创建、使用、更新定义和删除视图。

视图包含行和列,就像真实的表一样。视图中的字段源自数据库中一个或多个基础表中的字段。

使用视图的主要优点:

  • 简化性: 简化复杂的查询。用户可以查询视图,而无需了解底层表的结构或连接条件。
  • 安全性: 通过只向用户暴露特定列或行来限制数据访问,隐藏敏感信息。
  • 逻辑数据独立性: 如果底层表结构发生变化(例如,列重命名或拆分),有时可以修改视图定义以保持应用程序的接口一致,最大程度减少代码修改。
  • 可重用性: 只需定义一次通用的数据表示,即可在多个查询或应用程序中使用。

CREATE VIEW view_name AS SELECT column1, column2, … FROM table_name [WHERE condition] [GROUP BY …] [HAVING …] [ORDER BY …];

view_name: 您为视图指定的名称。

SELECT ...: 定义视图将呈现数据的标准 SQL SELECT 语句。它可以包含连接、函数、聚合等。

注意:视图始终反映其底层表中的当前数据。每次查询视图时,数据库引擎都会重新执行视图的 SQL 查询(除非它是物化视图)。

假设我们有 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。

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;

有时可以使用 INSERT、UPDATE 或 DELETE 语句在视图上修改底层基础表中的数据。但是,只有当数据库能够明确确定哪些基础表行和列受到影响时,视图才是可更新的。通常,如果视图满足以下条件,则是可更新的:

  • 基于单个表(或多个表,但 DML 操作仅影响一个基础表)。
  • 不使用聚合函数(SUM()、COUNT() 等)。
  • 不使用 GROUP BY 或 HAVING 子句。
  • 不使用 DISTINCT。
  • 在 SELECT 列表中不使用引用与 FROM 子句中相同表的子查询。
  • 基础表中所有没有默认值的 NOT NULL 列都包含在视图中并且可访问。

确切的规则可能因数据库系统而异。尝试更新不可更新的视图将导致错误。

要从数据库中移除视图,请使用 DROP VIEW 命令。

DROP VIEW view_name;

示例:

DROP VIEW ActiveProducts;

丢弃视图不会影响底层表中的数据。

实际应用场景:

  • 为报告仪表板创建 CustomerOrderSummary 视图。
  • 提供 PublicUserProfile 视图,隐藏敏感用户数据,如电子邮件或密码哈希。
  • 为定向营销活动构建 HighValueProducts 视图。