参考:

Sql — CTE公用表表达式和With用法总结

YouTube – SQL WITH Clause | How to write SQL Queries using WITH Clause | SQL CTE (Common Table Expression)

特色

1. CTE 可以引用自身, 实现递归查询. (Oracle 用 connect by prior)

2. 它有点像表变量, 其后的 query 都可以引用它. 然后自动销毁. 很方便

3. 可读性很棒

复用与可读性优化

来看一个例子, 有一个 product 表

go
create table product (
id int identity primary key,
name nvarchar(max) not null default '',
[group] nvarchar(max) not null default '',
price decimal not null default 0
); insert into product (name, [group], price) values
('product 1', 'group 1', 100),
('product 2', 'group 1', 100),
('product 3', 'group 1', 100),
('product 4', 'group 2', 100),
('product 5', 'group 2', 150),
('product 6', 'group 2', 100),
('product 7', 'group 3', 100),
('product 8', 'group 3', 50),
('product 9', 'group 3', 100);
go

需求是

1. 把 product group by [group], 并且计算出 sum price as total_price

2. 计算出 ave total_price

3. filter 出 total_price >= ave_total_price 的 group

Without CTE

首先是 group by [group] 语句

select [group], sum(price) as total_price from product group by [group];

然后是 ave 语句

select cast(avg(total.total_price) as int) as avg_price from (
select [group], sum(price) as total_price from product group by [group]
) total;

注意, 中间的语句是重复的 (管理扣分)

最后是

select [group], total_price from
(select [group], sum(price) as total_price from product group by [group]) pg
inner join
(select cast(avg(total.total_price) as int) as avg_price from
(
select [group], sum(price) as total_price from product group by [group]
) total
) pap
on pg.total_price >= pap.avg_price;

虽然结果是正确的, 但是语句重复很多, 可读性太差了.

With CTE

with
product_group as
(
select [group], sum(price) as total_price from product group by [group]
),
product_avg_price as
(
select cast(avg(total_price) as int) as avg_price from product_group
)
select [group], total_price from product_group pg inner join product_avg_price pap on
pg.total_price >= pap.avg_price;

没有了重复, 有了结构, 可读性大大提升.

递归 parent child tree

CTE 还有一个常用的地方是递归找出所有子层.

go
create table category (
id int identity primary key,
name nvarchar(256) not null default '',
parentId int null
);
alter table category add constraint fk_category_category_parentId foreign key (parentId) references category (id) on delete no action; insert into category (name, parentId) values
('category root', null),
('category layer 1 a', 1),
('category layer 1 b', 1),
('category later 2 aa', 2),
('category later 2 ba', 3),
('category later 3 aaa', 4),
('category later 3 aab', 4);
go

需求是找出 category layer 1 a 旗下的所有 category

with loop_category as (
select id, name, parentId from category where name = 'category layer 1 a'
union all
select c.id, c.name, c.parentId from category c inner join loop_category lc on c.parentId = lc.id
)
select * from loop_category;

关键就是 with as 里面可以 unial all loop_category 实现递归.

SQL Server CTE (Common Table Expression) 公用表表达式的更多相关文章

  1. CTE(Common Table Expression) 公用表表达式

    在编写T-SQL代码时,往往需要临时存储某些结果集.前面我们已经广泛使用和介绍了两种临时存储结果集的方法:临时表和表变量.除此之外,还可以 使用公用表表达式的方法.公用表表达式(Common Tabl ...

  2. SQLServer中的CTE(Common Table Expression)通用表表达式使用详解

    概述 我们经常会编写由基本的 SELECT/FROM/WHERE 类型的语句派生而来的复杂 SQL 语句.其中一种方案是需要编写在 FROM 子句内使用派生表(也称为内联视图)的 Transact-S ...

  3. with as (cte common table expression) 公共表表达式

    SQL中 with as 的用法——使用公用表表达式(CTE)  公用表表达式 (CTE) 可以认为是在单个 SELECT.INSERT.UPDATE.DELETE 或 CREATE VIEW 语句的 ...

  4. 【SQL Server】系统学习之一:表表达式

    本节讨论的相关内容包括:视图.派生表.CTE.内联表值函数 场景:如果要查询一组数据(例如聚合数据,也就是几个表聚合在一起的数据),这些数据并未在数据库中以表的形式存在. 1.视图:通常用来分解大型的 ...

  5. Sql — CTE公用表表达式和With用法总结

    CTE(Common Table Expression) 公用表表达式,它是在单个语句的执行范围内定义的临时结果集,只在查询期间有效.它可以自引用,也可在同一查询中多次引用,实现了代码段的重复利用. ...

  6. SQL Server进阶(六)表表达式--派生表、公用表表达式(CTE)、视图和内联表值函数

    概述 表表达式是一种命名的查询表达式,代表一个有效地关系表.可以像其他表一样,在数据处理中使用表表达式. SQL Server支持四种类型的表表达式:派生表,公用表表达式,视图和内联表值函数. 为什么 ...

  7. SQL Server 表表达式--派生表、公用表表达式(CTE)、视图和内联表值函数

    概述 表表达式是一种命名的查询表达式,代表一个有效地关系表.可以像其他表一样,在数据处理中使用表表达式. SQL Server支持四种类型的表表达式:派生表,公用表表达式,视图和内联表值函数. 为什么 ...

  8. 存储过程——公用表表达式(CTE)

    目录 0. 背景说明 1. 定义及语法细节 1.1 基本定义 1.2 基本语法 1.3 多个CTE同时声明 1.4 CTE嵌套使用 2. CTE递归查询 2.1 简介 2.2 准备工作 2.3 计算每 ...

  9. 公用表表达式CTE

    公用表表达式CTE表面上和派生表非常相似,看起来只是语义上的区别.但和派生表比较起来,CTE具有几个优势:第一,如果须要在一个CTE中引用另一个CTE,不需要像派生表那样嵌套,相反,只要简单地在同一个 ...

  10. SQL Server温故系列(3):SQL 子查询 & 公用表表达式 CTE

    1.子查询 Subqueries 1.1.单行子查询 1.2.多行子查询 1.3.相关子查询 1.4.嵌套子查询 1.5.子查询小结及性能问题 2.公用表表达式 CTE 2.1.普通公用表表达式 2. ...

随机推荐

  1. Divide Interval 题解

    背景 太逊了,调了三次才调出来,所以写篇题解寄念.LC好睿智 题意 给你两个数 \(a,b\),现在要从 \(a\) 跑到 \(b\),每次可以将当前的 \(a\) 拆分成 \(2^n\times m ...

  2. 学习笔记--初识Java面向对象

    面向对象与面向过程的区别 面向过程:主要关注具体过程,因果关系 优点:对于业务逻辑比较简单的程序,可以得到快速开发,前期投入成本比较低 缺点:由于面向过程的使用让程序间的元素"耦合度&quo ...

  3. 03-springboot使用单元测试和日志框架

    目录 1,springboot使用单元测试 2,使用日志框架 1,springboot使用单元测试 A:springboot使用单元测试需要引入一个单元测试启动器,该启动器的坐标为: <depe ...

  4. JMeter 后置处理器之JSON提取器

    后置处理器之JSON提取器 By:授客 QQ:1033553122 测试环境 JMeter 5.4.1 插件介绍 JSON后置处理器(PostProcessor)允许使用 JSON Path 语法从J ...

  5. 关于使用UE5打包Android的测试

    UE5打包Android,不同于UE4,在官方文档中需要Android studio 4.0或者3.5,还有Android SDK,NDK等 设置SetupAndroid, 在UE5 Editor配置 ...

  6. 【Java】Excel 读写图片工具类

    一.需求背景: 做一个大屏管理系统,基础信息包括管理的应用名称,大屏的截图,通过一个excel批量导入 excel的单元格里要插入图片,对应一个大屏应用的信息 导入需要读取到大屏截图,至于存哪还没说. ...

  7. 【H5】14 表单 其三 原生表单部件

    现在,我们将详细研究不同表单部件的功能,查看了哪些选项可用于收集不同类型的数据.这个指南有些详尽,涵盖了所有可用的原生表单小部件. 预备知识: 计算机基础知识和对于HTML的基本理解. 目标: 要了解 ...

  8. 【Ubuntu】下载安装 20.04.版本 桌面端

    下载 Download 这次的是直接在界面上下载的,我都不知道为什么怎么点到之前的版本去了 12.04.5远古版本界面怪难看的... [下载地址:点我访问] https://cn.ubuntu.com ...

  9. ubuntu18.04 源码方式安装wine , 警告,libxrender 64-bit development files not found, XRender won't be supported.

    警告信息: configure: WARNING: libxrender 64-bit development files not found, XRender won't be supported. ...

  10. python语言:通过对100个常用网站进行网络连接操作来判断当前的网络情况(是否被断掉)

    由于需要判断网络的通信情况,比如判断网络是否掉线,因此想到了一个笨方法,那就是对100个大型网站进行网络连接操作,通过是否连接成功来判断当前的网络是否被断掉. 这里的思路是只要大部分的网站可以连接通那 ...