使用 `WITH` 子句优化复杂 SQL 查询

使用 WITH 子句优化复杂 SQL 查询

在 SQL 中,处理复杂的查询需求时,代码往往会变得冗长且难以维护。为了解决这个问题,SQL 提供了 WITH 子句(也称为公用表表达式,Common Table Expression,CTE)。WITH 子句允许我们定义临时表,将复杂的查询逻辑分解为多个简单的部分,从而提高代码的可读性和可维护性。本文将详细介绍 WITH 子句的使用方法,并通过一个实际案例展示其强大功能。


什么是 WITH 子句?

WITH 子句是 SQL 中用于定义临时表的一种语法结构。它允许我们在一个查询中创建多个临时表,这些临时表可以在后续的查询中被引用。WITH 子句的主要优点包括:

  1. 提高代码可读性:通过将复杂的查询逻辑分解为多个简单的部分,代码更易于理解和维护。
  2. 避免重复代码:临时表可以在查询中多次引用,避免重复编写相同的子查询。
  3. 支持递归查询WITH 子句还支持递归查询,可以用于处理层次结构数据(如树形结构)。

WITH 子句定义的临时表仅在当前查询中有效,查询结束后会自动销毁,因此不会对数据库产生持久性影响。


WITH 子句的基本语法

WITH 子句的基本语法如下:

WITH 临时表名 AS (
    SELECT 查询语句
)
SELECT 查询语句;
  • 临时表名:为临时表定义的名称。
  • SELECT 查询语句:定义临时表的具体查询逻辑。
  • WITH 子句之后,可以使用定义的临时表进行进一步的查询。

实际案例:学生成绩查询系统

假设我们有一个学生成绩管理系统,包含以下四张表:

  1. tb_student:学生信息表,包含学生的 idnameclass_id
  2. tb_class:班级信息表,包含班级的 idclass_name
  3. tb_teacher:教师信息表,包含教师的 idname
  4. tb_subject:课程信息表,包含课程的 idnameteacher_id
  5. tb_score:成绩信息表,包含学生的 stu_id、课程的 subject_id 和成绩 score

我们的目标是查询某个学生(例如姓名为 AAA 的学生)的所有成绩信息,包括学生姓名、班级名称、课程名称和成绩。

1. 定义临时表 temp

首先,我们定义一个临时表 temp,用于查询学生的基本信息和班级名称:

WITH temp AS (
    SELECT t.*, c.class_name 
    FROM tb_student t 
    LEFT JOIN tb_class c ON t.class_id = c.id 
)
  • 通过 LEFT JOINtb_student 表和 tb_class 表关联,获取学生的班级名称。
  • temp 表包含学生的所有信息以及他们所在班级的名称。

2. 定义临时表 temp2

接下来,我们定义第二个临时表 temp2,用于查询教师教授的课程信息:

temp2 AS (
    SELECT t.*, s.name AS subject_name, s.id AS subject_id 
    FROM tb_teacher t 
    LEFT JOIN tb_subject s ON t.id = s.teacher_id  
)
  • 通过 LEFT JOINtb_teacher 表和 tb_subject 表关联,获取教师教授的课程名称和课程 ID。
  • temp2 表包含教师的所有信息以及他们所教授的课程名称和课程 ID。

3. 使用临时表进行最终查询

最后,我们使用 temptemp2 临时表进行最终查询,获取学生的成绩信息:

SELECT DISTINCT t.* 
FROM temp t 
LEFT JOIN tb_score s ON t.id = s.stu_id 
LEFT JOIN temp2 AS k ON k.subject_id = s.subject_id 
WHERE t.name = 'AAA';
  • 通过 LEFT JOINtemp 表与 tb_score 表关联,获取学生的成绩信息。
  • 再通过 LEFT JOINtemp2 表与 tb_score 表关联,获取课程的名称。
  • 使用 WHERE 条件筛选出姓名为 AAA 的学生。

完整 SQL 查询

将上述步骤整合在一起,完整的 SQL 查询如下:

WITH temp AS (
    SELECT t.*, c.class_name 
    FROM tb_student t 
    LEFT JOIN tb_class c ON t.class_id = c.id 
),
temp2 AS (
    SELECT t.*, s.name AS subject_name, s.id AS subject_id 
    FROM tb_teacher t 
    LEFT JOIN tb_subject s ON t.id = s.teacher_id  
)
SELECT DISTINCT t.* 
FROM temp t 
LEFT JOIN tb_score s ON t.id = s.stu_id 
LEFT JOIN temp2 AS k ON k.subject_id = s.subject_id 
WHERE t.name = 'AAA';

总结

通过 WITH 子句,我们可以将复杂的查询逻辑分解为多个简单的部分,从而提高代码的可读性和可维护性。在实际开发中,WITH 子句特别适用于以下场景:

  1. 多层嵌套查询:将嵌套的子查询提取为临时表,使代码更清晰。
  2. 递归查询:处理层次结构数据(如组织架构、树形结构)。
  3. 复杂数据分析:将多个步骤的查询逻辑分解为多个临时表,便于调试和优化。

掌握 WITH 子句的使用方法,可以显著提升 SQL 查询的编写效率和代码质量。希望本文的案例和讲解能帮助你更好地理解和应用 WITH 子句!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/966092.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

jvm 篇

字节码的作用 ‌跨平台性‌:字节码是Java实现跨平台特性的关键。Java源代码编译成字节码后,可以在任何安装了Java虚拟机(JVM)的设备上运行,这使得Java应用程序能够在不同的操作系统和硬件平台上运行而无需重新编译。‌…

【Springboot】Springboot 自定义线程池的参数配置最优是多少

博主介绍:✌全网粉丝22W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…

【2】Cisco SD-WAN 组件介绍

1. 概述 Cisco SD-WAN 是一套基于软件定义的广域网(SD-WAN)解决方案,能够提供安全、可扩展且高效的网络连接。它通过集中的控制和智能路径选择,实现跨多个站点的可靠性、可见性和优化。 在 Cisco SD-WAN 体系架构中,主要由四个核心组件构成: vManage(管理平面) vSmart…

测试中的第一性原理:回归本质的质量思维革命

在软件工程领域,测试活动常被惯性思维和经验主义所主导——测试用例库无限膨胀、自动化脚本维护成本居高不下、测试策略与业务目标渐行渐远。要突破这种困境,第一性原理(First Principles Thinking)提供了独特的解题视角&#xff…

《chatwise:DeepSeek的界面部署》

ChatWise:DeepSeek的界面部署 摘要 本文详细描述了DeepSeek公司针对其核心业务系统进行的界面部署工作。从需求分析到技术实现,再到测试与优化,全面阐述了整个部署过程中的关键步骤和解决方案。通过本文,读者可以深入了解DeepSee…

机器学习在癌症分子亚型分类中的应用

学习笔记:机器学习在癌症分子亚型分类中的应用——Cancer Cell 研究解析 1. 文章基本信息 标题:Classification of non-TCGA cancer samples to TCGA molecular subtypes using machine learning发表期刊:Cancer Cell发表时间:20…

什么是AIOps?

AIOps(人工智能运维,Artificial Intelligence for IT Operations)是通过使用人工智能(AI)技术来增强 IT 运维(IT Operations)的智能化、自动化和效率的概念。它结合了机器学习、数据分析、自动化…

使用deepseek快速创作ppt

目录 1.在DeekSeek生成PPT脚本2.打开Kimi3.最终效果 DeepSeek作为目前最强大模型,其推理能力炸裂,但是DeepSeek官方没有提供生成PPT功能,如果让DeepSeek做PPT呢? 有个途径:在DeepSeek让其深度思考做出PPT脚本&#xf…

DeepSeek 引领的 AI 范式转变与存储架构的演进

近一段时间,生成式 AI 技术经历了飞速的进步,尤其是在强推理模型(Reasoning-LLM)的推动下,AI 从大模型训练到推理应用的范式发生了剧变。以 DeepSeek 等前沿 AI 模型为例,如今的 AI 技术发展已不局限于依赖…

vscode 设置在编辑器的标签页超出可视范围时自动换行(workbench.editor.wrapTabs)

“workbench.editor.wrapTabs”: true 是 VS Code(Visual Studio Code) 的一个设置项,它的作用是 在编辑器的标签页超出可视范围时自动换行,而不是显示滚动条。 需要修改settings.json 参考:settings.json 默认值&a…

高端入门:Ollama 本地高效部署DeepSeek模型深度搜索解决方案

目录 一、Ollama 介绍 二、Ollama下载 2.1 官网下载 2.2 GitHub下载 三、模型库 四、Ollmal 使用 4.1 模型运行(下载) 4.2 模型提问 五、Ollama 常用命令 相关推荐 一、Ollama 介绍 Ollama是一个专为在本地机器上便捷部署和运行大型语言模型&…

前端组件标准化专家Prompt指令的最佳实践

前端组件标准化专家Prompt 提示词可作为项目自定义提示词使用,本次提示词偏向前端开发的使用,如有需要可适当修改关键词和示例 推荐使用 Cursor 中作为自定义指令使用Cline 插件中作为自定义指令使用在力所能及的范围内使用最好的模型,可以…

介绍10个比较优秀好用的Qt相关的开源库

记录下比较好用的一些开源库 1. Qt中的日志库“log4qt” log4qt 是一个基于 Apache Log4j 设计理念的 Qt 日志记录库,它为 Qt 应用程序提供了强大而灵活的日志记录功能。Log4j 是 Java 领域广泛使用的日志框架,log4qt 借鉴了其优秀的设计思想&#xff…

如何打造一个更友好的网站结构?

在SEO优化中,网站的结构往往被忽略,但它其实是决定谷歌爬虫抓取效率的关键因素之一。一个清晰、逻辑合理的网站结构,不仅能让用户更方便地找到他们需要的信息,还能提升搜索引擎的抓取效率 理想的网站结构应该像一棵树,…

态、势、感、知中的信息

“态、势中的信息”与“感、知中的信息”分别对应客观系统状态与主观认知过程的信息类型,其差异体现在信息的来源、性质、处理方式及作用目标上。以下通过对比框架和具体案例解析两者的区别: 态势中的信息中的态信息指系统在某一时刻的客观存在状态&…

文本生图的提示词prompt和参数如何设置(基于Animagine XL V3.1)

昨天搞了半天 Animagine XL V3.1,发现市面上很多教程只是授之以鱼,并没有授之以渔的。也是,拿来赚钱不好吗,闲鱼上部署一个 Deepseek 都能要两百块。这里我还是想写篇文章介绍一下,虽不全面,但是尽量告诉你…

基于docker搭建Kafka集群,使用内部自带的Zookeeper方式搭建

前提条件 按照【kafka3.8.0升级文档成功搭建kafka服务】 环境:192.168.2.91 192.168.2.93 并以192.168.2.91环境kafka自带的zookeeper作为协调器。 使用基于KRaft方式进行kafka集群搭建教程 搭建kafka-ui可视化工具 1、创建kafka集群节点192.168.2.91 &#xff…

GitPuk快速安装配置教程(入门级)

GitPuk是一款国产开源免费的代码管理工具,工具简洁易用,开源免费,本文将讲解如何快速安装和配置GitPuk,以快速入门上手。 1、安装 支持 Windows、Mac、Linux、docker 等操作系统。 1.1 Linux安装 以下以Centos7安装…

奖励模型中的尺度扩展定律和奖励劫持

奖励模型中的尺度扩展定律和奖励劫持 FesianXu 20250131 at Wechat Search Team 前言 最近在考古一些LLM的经典老论文,其中有一篇是OpenAI于ICML 2023年发表的文章,讨论了在奖励模型(Reward Model)中的尺度扩展规律(S…

ASP.NET Core中Filter与Middleware的区别

中间件是ASP.NET Core这个基础提供的功能,而Filter是ASP.NET Core MVC中提供的功能。ASP.NET Core MVC是由MVC中间件提供的框架,而Filter属于MVC中间件提供的功能。 区别 中间件可以处理所有的请求,而Filter只能处理对控制器的请求&#x…