news 2026/4/3 7:16:17

SQL 中的 WITH ... AS ...

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SQL 中的 WITH ... AS ...

SQL 中的WITH ... AS ...是一种非常强大且常用的语法结构,用于定义公用表表达式(Common Table Expression,简称CTE)。它可以帮助你将复杂的查询拆解为更清晰、可读性更强的逻辑块。


一、基本语法

WITH cte_name AS ( -- 子查询(SELECT 语句) SELECT ... ) SELECT * FROM cte_name;
  • cte_name:你给这个临时结果集起的名字(类似一个临时视图)。
  • AS (...):括号内是一个标准的SELECT查询,不能包含INSERTUPDATEDELETE等 DML 语句。
  • CTE 只在当前语句中有效,执行完就释放,不会持久化。

二、为什么用 CTE?

  1. 提高可读性:把复杂逻辑分解成多个步骤。
  2. 避免重复子查询:如果同一个子查询要用多次,用 CTE 定义一次即可。
  3. 支持递归查询:这是 CTE 最强大的特性之一(如查询组织架构、树形结构等)。

三、简单示例

假设有一张员工表employees(id, name, manager_id, salary)

示例 1:非递归 CTE

找出工资高于平均工资的员工:

WITH avg_salary AS ( SELECT AVG(salary) AS avg_sal FROM employees ) SELECT e.name, e.salary FROM employees e JOIN avg_salary a ON e.salary > a.avg_sal;

这里avg_salary是一个只含一行一列的临时表,供主查询使用。


示例 2:多个 CTE(用逗号分隔)

WITH high_earners AS ( SELECT id, name, salary FROM employees WHERE salary > 100000 ), dept_counts AS ( SELECT department_id, COUNT(*) AS emp_count FROM employees GROUP BY department_id ) SELECT h.name, h.salary, d.emp_count FROM high_earners h JOIN employees e ON h.id = e.id JOIN dept_counts d ON e.department_id = d.department_id;

多个 CTE 之间用逗号分隔,最后一个 CTE 后直接跟主查询。


四、递归 CTE(Recursive CTE)

用于处理层级结构树形数据,比如:公司组织架构、评论的父子关系、物料清单等。

递归 CTE 语法:

WITH RECURSIVE cte_name AS ( -- 初始查询(锚点成员) SELECT ... UNION ALL -- 递归查询(引用自身) SELECT ... FROM cte_name JOIN ... ) SELECT * FROM cte_name;

注意:有些数据库(如 PostgreSQL、MySQL 8.0+、SQL Server)需要写WITH RECURSIVE,而有些(如 SQL Server)只需WITH即可自动识别递归。

示例:查询某员工的所有下属(多级)

WITH RECURSIVE subordinates AS ( -- 锚点:从某个经理开始(比如 id = 1) SELECT id, name, manager_id, 0 AS level FROM employees WHERE id = 1 UNION ALL -- 递归:找下一级员工 SELECT e.id, e.name, e.manager_id, s.level + 1 FROM employees e INNER JOIN subordinates s ON e.manager_id = s.id ) SELECT * FROM subordinates;

这会返回 ID 为 1 的员工及其所有直接/间接下属,并标注层级深度。


五、注意事项

数据库是否支持 CTE是否需要RECURSIVE关键字
PostgreSQL需要(递归时)
MySQL 8.0+需要(递归时)
SQL Server不需要(自动识别)
Oracle不需要(但可用)
SQLite 3.8.3+需要(递归时)
旧版 MySQL(<8.0)不支持

六、CTE vs 子查询 vs 临时表

特性CTE子查询临时表
可读性⭐⭐⭐⭐⭐⭐⭐⭐⭐
性能通常与子查询相当(优化器会重写)同左可能更快(可加索引)
作用域仅当前语句仅当前查询块当前会话
支持递归❌(除非手动循环)
可重复引用✅(多次)❌(需复制)

七、总结

  • WITH ... AS ...定义的是临时命名结果集(CTE)。
  • 适用于简化复杂查询、提升可读性、实现递归逻辑。
  • 在现代 SQL 开发中几乎是必备技能。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/2 12:03:08

基于金枪鱼群优化算法优化人工神经网络预测附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 &#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室 &#x1f447; 关注我领取海量matlab电子书…

作者头像 李华
网站建设 2026/4/3 1:04:58

小众穿戴甲定价10美金,竟在独立站卖疯了。

“不是美甲做不起&#xff0c;而是穿戴甲更有性价比”。如果你近两年关注美甲和穿戴甲市场&#xff0c;你就不可能不知道“穿戴甲跨境”这个龙卷风口。Glamermaid 这个品牌&#xff0c;凭借 10 美金的穿戴甲&#xff0c;在独立站的低客单价品类杀出了一条血路&#xff0c;把小生…

作者头像 李华
网站建设 2026/4/1 22:25:51

2026年上半年软考高项是报班还是自学?

作为一名非学霸、没备考经验还得边上班边挤时间学的过来人&#xff0c;当初备战高项时&#xff0c;我也纠结过 “自学到底行不行”“有没有必要报班”。后来既试过自学硬扛&#xff0c;也体验过报班系统学&#xff0c;算是把两种方式的利弊摸得透透的 —— 自学不是完全不行&am…

作者头像 李华
网站建设 2026/3/29 5:15:27

基于微信小程序的私房菜定制上门服务系统

文章目录详细视频演示项目介绍技术介绍功能介绍核心代码系统效果图源码获取详细视频演示 文章底部名片&#xff0c;获取项目的完整演示视频&#xff0c;免费解答技术疑问 项目介绍 在消费升级与个性化需求增长的背景下&#xff0c;传统餐饮服务模式面临标准化菜品占比高、体验…

作者头像 李华
网站建设 2026/3/28 8:00:31

【OpenMesh】OpenMesh实现增量网格重构

【OpenMesh】OpenMesh实现增量网格重构 本文实现的为增量网格重构&#xff08;incremental remesh&#xff09;算法思想如下&#xff1a; 接收一个目标边长作为输入&#xff1b;遍历所有边&#xff0c;边长度大于目标边长的4/3时&#xff0c;认为是长边&#xff0c;将在该边中…

作者头像 李华
网站建设 2026/4/1 22:00:15

Clawdbot架构深度剖析 - 大模型Agent设计与底层原理解析

Clawdbot(OpenClaw)是一种基于TypeScript的智能个人助理&#xff0c;文章详细解析了其架构组件&#xff1a;频道适配器、网关服务器、Agent执行器等&#xff0c;特别介绍了其创新记忆系统(会话转录和记忆文件)和安全性机制。该系统能在本地执行工具操作&#xff0c;使用语义快照…

作者头像 李华