WITH 子句

最近更新时间:2026-05-06 16:28:13

我的收藏
WITH 子句允许在 SELECTINSERTUPDATE 语句之前定义一个或多个临时结果集,这些结果集被称为公用表表达式 (CTE)。它类似于定义了仅在当前查询范围内有效的“局部视图”。

核心价值

消除冗余(方便维护):将多次引用的复杂子查询提取到顶部,减少代码重复,降低维护成本。
提升可读性:将嵌套过深、逻辑复杂的 SQL “扁平化”,使其更接近人类阅读习惯(从上到下执行逻辑)。
冲突隔离:定义的别名仅在当前查询结束后即销毁,不会与数据库中的实际表名或视图名产生冲突。
跨系统兼容:广泛支持 ANSI SQL 标准(如 Oracle、PostgreSQL、MySQL 8.0+ 等),增强了代码的可移植性。

使用限制

递归支持:当前版本不支持递归查询(即 WITH RECURSIVE),而某些其他数据库系统支持该功能。

代码示例

多重定义与引用

-- 定义两个临时表 t1 和 t2,并执行合并插入
WITH
t1 AS (SELECT 1 AS val),
t2 AS (SELECT 2 AS val)
INSERT INTO tab
SELECT * FROM t1
UNION ALL
SELECT * FROM t2;

嵌套作用域定义

CTE 也支持在不同查询层级进行定义。以下示例展示了外层定义与内层嵌套定义的结合使用:
-- 在外层定义 t1,同时在 UNION ALL 的分支内局部定义 t2
WITH t1 AS (SELECT 1)
(
WITH t2 AS (SELECT 2)
SELECT * FROM t2
)
UNION ALL
SELECT * FROM t1;

与传统子查询对比

特性
传统子查询 (Subquery)
WITH 子句 (CTE)
逻辑顺序
由内而外(嵌套式)
由上而下(流式)
复用性
无法直接复用,需多次书写逻辑
一次定义,多次引用
代码维护
随着嵌套加深,代码极难维护
逻辑清晰,易于调试