WITH 子句(Common Table Expressions, CTE)和视图

119 阅读4分钟

WITH 子句(也被称为公共表表达式或 CTEs)和视图(Views)都是 SQL 查询中用来简化复杂查询和改善查询组织的工具,但它们有一些关键的区别。以下是 WITH 子句和视图之间的一些详细对比:

生命周期与范围

  • WITH子句 (CTE): CTEs 创建的是临时的结果集,它们只在包含它们的 SQL 查询执行期间存在。执行结束后,CTE 定义的临时结果集就会被释放,不会被数据库系统持久存储。

  • 视图 (View): 视图是数据库级别的对象,可以被存储、管理和多次使用。一旦创建,视图会持久存在于数据库中,直到被显式删除。视图充当查询的模板,每次引用它时都会重新执行其背后的查询逻辑。

定义与调用

  • WITH子句 (CTE): CTE 在查询的开始部分定义,并且只能在紧随其后的那个查询中被调用。它们通常被用于组织复杂查询,特别是涉及到递归或多个相互依赖的子查询时。

  • 视图 (View): 视图是使用 CREATE VIEW 语句定义的,可以在任何查询、视图或者存储过程中被多次调用。它们是数据库结构的一部分,通常用于封装常用的查询逻辑,并且为用户提供简化的数据接口。

更新性

  • WITH子句 (CTE): CTEs 本身不能被直接更新,因为它们的临时性质。但你可以执行更新包含 CTE 的查询。在修改数据时,需要指明要操作的基础表。

  • 视图 (View): 某些类型的视图(如简单视图或更新视图)支持更新,这将影响底层基表的数据。然而,并非所有的视图都可以被更新,这通常依赖于其定义中的复杂度。

性能

  • WITH子句 (CTE): CTE 的执行性能可能受到其使用方式的影响。在某些情况下,数据库可能会对包含在 CTE 中的查询进行优化。

  • 视图 (View): 视图本身不存储数据(除非是物化视图),因此其性能取决于视图定义中的查询性能以及数据库如何执行这些查询。每次查询视图时,其背后的查询都会执行。

使用场景

  • WITH子句 (CTE): 适合一次性的复杂查询、需要分步解释的查询,或者那些包含递归逻辑的查询。

  • 视图 (View): 适合需要重复使用的查询逻辑、需要封装以简化用户访问的查询,或者用于数据访问控制和安全性层面的封装。

综上所述,WITH 子句是为了一次性提升查询的可读性和组织性,而视图是为了重用查询逻辑、实现数据访问层的抽象化。选择使用哪一个取决于你的具体需求、数据库设计以及管理的方便性。

支持 WITH 子句 (CTE) 的数据库和版本信息:

数据库系统数据库类型SQL 标准遵循从版本开始支持
PostgreSQL关系型SQL:19998.4 (2009年)
MySQL关系型SQL:19998.0 (2018年)
Microsoft SQL Server关系型SQL:19992005 (2005年)
Oracle Database关系型SQL:19999i (2001年)
SQLite关系型SQL:19993.8.3 (2014年)
IBM DB2关系型SQL:19999.7 (2009年)
SAP HANA关系型SQL:19991.0 (2010年)
MariaDB关系型SQL:199910.2 (2017年)
Apache Hive数据仓库SQL:19990.13.0 (2014年)
Amazon Redshift数据仓库SQL:1999初始版本
Snowflake数据仓库SQL:1999初始版本

支持视图的数据库和版本信息:

数据库系统数据库类型SQL 标准遵循视图支持情况
PostgreSQL关系型SQL-92早期版本就支持
MySQL关系型SQL-925.0 (2005年)
Microsoft SQL Server关系型SQL-92早期版本就支持
Oracle Database关系型SQL-92早期版本就支持
SQLite关系型SQL-92早期版本就支持
IBM DB2关系型SQL-92早期版本就支持
SAP HANA关系型SQL-92初始版本
MariaDB关系型SQL-92初始版本
Apache Hive数据仓库HiveQL0.12.0 (2013年)

请注意,这里的 "SQL 标准遵循" 是用来大致表示数据库系统支持的 SQL 标准级别,实际上各个数据库系统可能有自己的 SQL 方言差异。此外,即使在支持视图的数据库中,也可能存在不同级别的支持,例如是否支持物化视图(Materialized Views),以及视图是否是可更新的(Updatable Views)等。

鉴于数据库技术的迅速发展,特性的支持情况和数据库的版本信息应该以官方文档为准,这份列表仅供参考。在实际应用中,请确保按照你使用的具体数据库版本来设置和执行 SQL 语句。