深入理解 SQL 中的 WITH AS 语法

ops/2024/10/25 8:56:32/

在日常数据库操作中,SQL 语句的复杂性往往会影响到查询的可读性和维护性。为了解决这个问题,Oracle 提供了 WITH AS 语法,这一功能可以极大地简化复杂查询,提升代码的清晰度。本文将详细介绍 WITH AS 的基本用法、优势以及一些实际应用示例。

1. 什么是 WITH AS

WITH AS 语法又称为公共表表达式(CTE,Common Table Expression),允许开发者在一个查询中定义一个或多个临时结果集,这些结果集可以在随后的主查询中被引用。通过这种方式,开发者可以将复杂的查询逻辑分解为更易于理解和维护的多个部分。
基本语法
基本的 WITH AS 语法结构如下:

WITH CTE_name AS (SELECT column1, column2FROM table_nameWHERE condition
)
SELECT *
FROM CTE_name;

2. 使用 WITH AS 的优势

2.1 提高可读性

复杂的 SQL 查询往往涉及多个嵌套的子查询,这不仅增加了代码的长度,还使得理解查询逻辑变得困难。通过 WITH AS,我们可以将逻辑划分为多个部分,每个部分清晰地命名,便于其他开发者或未来的自己快速理解。

2.2 避免重复计算

在一些复杂查询中,同一个计算可能会被多次调用。如果我们在每个地方都写相同的子查询,既浪费了资源,又降低了代码的可维护性。使用 WITH AS 可以只计算一次,然后在后续的查询中重用这个结果集。

2.3 递归查询支持

Oracle 的 WITH AS 还支持递归查询,这对于处理层级数据(如组织结构、文件系统等)非常有用。通过递归 CTE,开发者可以轻松地获取父子关系数据。

3. 实际应用示例

示例 1:计算平均工资

假设我们有一个员工表 employees,我们想找出工资高于 10000 的员工,并计算他们的平均工资:

WITH    employeesTemp AS (SELECT * FROM employees WHERE salary > 10000
)
SELECT AVG(salary) AS highSalary FROM employeesTemp;

在这个例子中,我们首先定义了一个临时表 employeesTemp,它包含所有工资超过 10000 的员工。随后,我们利用这个临时表计算这些员工的平均工资。

示例2:计算近10天特定时间段新增数据占比全天比例

WITH total_counts AS (
SELECTtrunc(t.CREATED_TIME) AS DAY,count(1) AS total_count
FROMt_user t
WHEREt.CREATED_TIME > SYSDATE - 10
GROUP BYtrunc(t.CREATED_TIME)
),
afternoon_counts AS (
SELECTtrunc(t.CREATED_TIME) AS DAY,count(1) AS afternoon_count
FROMt_user t 
WHEREt.CREATED_TIME > SYSDATE - 10AND TO_CHAR(t.CREATED_TIME, 'HH24') BETWEEN '15' AND '17'
GROUP BYtrunc(t.CREATED_TIME)
)
SELECTt.day,t.total_count,a.afternoon_count,ROUND(a.afternoon_count / t.total_count * 100, 2) AS percentage
FROMtotal_counts t
LEFT JOINafternoon_counts a ONt.day = a.day
ORDER BYt.day;

在这个例子中,我们首先定义了临时表total_counts和afternoon_counts,其中afternoon_counts统计的是下午15~17点数据量,最后临时表total_counts和afternoon_counts关联查询,统计出近10天内15~17点数据量占比全天数据比例
在这里插入图片描述

4. 小结

WITH AS 语法在 SQL 查询中提供了一个强大的工具,可以帮助开发者构建更清晰、更高效的查询逻辑。通过提高可读性、避免重复计算和支持递归查询。在实际开发中,合理使用这一语法可以显著提升代码的质量与维护性。


http://www.ppmy.cn/ops/128282.html

相关文章

Day16-非关系型数据库服务-redis

Day16-非关系型数据库服务-redis 1、非关系型数据库服务Redis1.1 Redis服务概述介绍1.1.1 缓存服务介绍1.1.2 缓存服务产品介绍1.1.3 缓存服务应用场景 1.2 Redis服务安装部署1.2.1 缓存服务安装部署 1.3 Redis服务基础管理操作1.3.1 缓存服务配置文件介绍1.3.2 缓存服务安全配…

spring (Aop) day 1024

ok了家人们,继续学习spring ,这段知识点有点绕,建议搭配b站的视频去学,passion!!! 八.AOP-面向切面编程 8.1 动态代理 8.1.1 概述 什么是代理?在现实生活中,代理很常见…

.NET 9 - 尝试一下Open Api 的一些变化

1.简单介绍 .NET 9 中 OpenAPI 也有一些变化,这边也简单体验一下.NET 9 中的OpenAPI的变化,具体的话,可以参考如下文章,谢谢 .NET 9 OpenAPI 2. .NET 8的OpenAPI 这边以Visual Studio 2022中的ASP.NET Core Minimal API模板来…

十七、行为型(命令模式)

命令模式(Command Pattern) 概念 命令模式是一种行为型设计模式,它将请求封装成一个对象,从而使您可以使用不同的请求对客户进行参数化,排队请求,以及支持可撤销操作。通过这种模式,调用操作的…

Kubernetes:(二)K8Sv1.20二进制部署

文章目录 一、k8s项目架构二、二进制搭建 Kubernetes v1.20 (单master节点)1.操作系统初始化配置2.部署 docker引擎3. etcd的概念4. 证书认证5. node01 节点操作(192.168.44.10)6. node02 节点操作(192.168.44.40&…

Maven学习笔记

目录 一、什么是Maven 二、maven下载和安装目录 1、安装目录解析 2、maven仓库 二、maven项目创建(Hello) 四、maven项目操作 五、创建HelloFriend 六、maven项目中pom.xml标签解释 1、坐标 2、依赖 (1)依赖的范围 &a…

Java最全面试题->Java主流框架->Zuukeeper面试题

文章目录 ZuukeeperZooKeeper是什么?ZooKeeper和dubbo的区别?Zookeeper的java客户端都有哪些?ZooKeeper提供了什么?说说ZooKeeper文件系统说说ZAB协议?Znode有哪些类型?Zookeeper节点宕机如何处理?Zookeeper有哪几种几种部署模式?Zookeeper的典型应用场景?说一下Zooke…

开启RefCell debug_refcell feature查看借用冲突位置

文章目录 背景分析解决方法 本文解决两个问题: 开启rust源码库中的feature开启debug_refcell feature的方法查看 borrow 借用冲突的位置 背景 使用 RefCell 来实现内部可变性是在 Rust 开发中常用的方式,但是当逻辑复杂起来,常常会有可变借…