参考:

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. linux系统是未来_大小写敏感_case_sensitive_编程原生态

    修改 py 文件 回忆上次内容 上次尝试了 两个vim 同时打开 同一py文件 vim出现了Error 有各种选择     错误拼写 pront 导致 运行时 出现了NameError         ...

  2. Day 4 - 搜索进阶与模拟

    启发式搜索 下面将简要介绍启发式搜索及其用法. 定义 启发式搜索(英文:\(\text{heuristic search}\))是一种在普通搜索算法的基础上引入了启发式函数的搜索算法. 启发式函数的作 ...

  3. 《最新出炉》系列入门篇-Python+Playwright自动化测试-54- 上传文件(input控件) - 上篇

    1.简介 在实际工作中,我们进行web自动化的时候,文件上传是很常见的操作,例如上传用户头像,上传身份证信息等.所以宏哥打算按上传文件的分类对其进行一下讲解和分享. 2.上传文件的API(input控 ...

  4. RESTful服务与swagger

    一开始刚学springboot的时候 restful服务+swagger一点都看不懂,现在知识学了一些,再回头看这些东西就简单很多了. 自己跟视频做了一个零件项目,里面写了一些零零散散的模块,其中在视 ...

  5. 【Hbase】1.3.1版本安装

    环境: 1核4G内存128G磁盘,三台机器同一个配置 192.168.242.131 192.168.242.132 192.168.242.133 -- Linux Centos7 x64 系统平台 ...

  6. 图床、云对象存储、CDN业务:“自定义 CDN 加速域名” 与 “自定义源站域名” 的区别

    参考: https://developer.qiniu.com/kodo/8622/dev-the-binding-source-domain-name ----------------------- ...

  7. obs 直播软件 虚拟摄像头插件 —— obs-virtualcam

    如题: 外网下载地址: https://github.com/Fenrirthviti/obs-virtual-cam/releases 这个东西是做啥用的这里就不讲了,这个东西的资源不好找,找了好半 ...

  8. 通过 C# 将数据写入到Excel表格

    Excel 是一款广泛应用于数据处理.分析和报告制作的电子表格软件.在商业.学术和日常生活中,Excel 的使用极为普遍.本文将详细介绍如何使用免费.NET库将数据写入到 Excel 中,包括文本.数 ...

  9. Linux内存占用分析的几个方法,你知道几个?

    0. 引言: 系统内存是硬件系统中必不可少的部分,定时查看系统内存资源运行情况,可以帮助我们及时发现内存资源是否存在异常占用,确保业务的稳定运行. 例如:定期查看公司的网站服务器内存使用情况,可以确保 ...

  10. 【前端js】之小数点保留时的四舍五入问题

    项目遇到金额小数点保留位数,极个别的数会差一分,经调查是因为js的问题. 解决办法: # 方法一:保留两位小数 function keepTwoDecimal(num) { var result = ...