当前位置: 首页 > news >正文

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 开发中几乎是必备技能。
http://www.jsqmd.com/news/339316/

相关文章:

  • 数据不再混乱!JSON Crack 可视化 + cpolar,随时随地搞定复杂数据协作
  • mycat报错:63529
  • Python正则表达式终极指南:从模式匹配到文本工程的智能跃迁
  • 基于金枪鱼群优化算法图像重构附Matlab代码
  • DeepSeek-OCR 2:视觉因果流模型官方论文解读总结
  • 金仓赋能:关系数据库替换高效落地,Oracle 平滑迁移
  • 适配FOUP载具的晶圆搬运机械手,哪些型号维护更便捷?
  • 教师狂喜❗️魔果云课直接拉满教学效率[特殊字符]
  • 跨团队协作怎么做:一套可落地的研发项目管理框架与工具
  • 【程序员必学】GPT模型架构解析:预训练与微调技术详解(建议收藏)
  • 重塑机器人轻量化设计:PEEK精密注塑结构件壳体_高强度耐磨损
  • KingBase 备份操作手册
  • 收藏级|大模型学习不踩坑!小白程序员必看的“3阶9步”极简入门框架
  • 《升鲜宝供应链管理系统 功能详情说明(完整版)》
  • 从架构设计到实战策略:如何让公有云多可用区部署“永不宕机”?
  • 收藏必备!大模型智能体8大核心概念全解析,程序员入门必看指南
  • 加入大厂,却落入了边缘业务:这是职业选择的必然代价吗?
  • 从入门到年薪百万:AI大模型学习路线与技能图谱(必收藏)
  • 【强烈推荐】大模型Agent实战指南:能“自己想、自己干、自己复盘“的才是好Agent,5大主流框架对比与应用
  • 上海靠谱电子产品开发,实邦电子经验丰富吗?
  • 厦门大学等突破AI自学限制:让计算机为自己量身定制学习计划
  • AI提示设计中,如何让用户“有成就感”?提示工程架构师的4个技巧
  • 程序员的价值与社会贡献
  • Linux系统架构理解
  • “入坑网安后悔一时,不入坑后悔一辈子!” 数字世界的守护者们,共勉!
  • 让大模型能自己想出安全方案——KAIST团队的突破性研究
  • 探索AI提示工程国际化与本地化,提示工程架构师的独特视角
  • openclaw(大龙虾)+飞书保姆级windows安装教程
  • 全面评测2026年免费降低AI率工具,那款工具降AI率最有效?
  • 农作物病虫害检测识别系统|基于YOLOv11+Pytorch + Flask + > SpringBoot|支持玉米、水稻、番茄、草莓病害检测(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定