参考:

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. Mysql密码安全策略修改

    Mysql5.7默认有密码安全策略,密码安全级别要求比较高,在测试环境中使用起来不方便,本经验将介绍如何修改Mysql的密码安全策略,解决ERROR 1819错误. 1:首先使用root用户连接mys ...

  2. webpack4.15.1 学习笔记(四) — Tree shaking

    目录 Tree shaking 原理 标记效果 副作用代码不可被删除 如何实现 Tree shaking 的几种方法 总结 Tree shaking 本质上为了消除无用的js代码,减少加载文件体积的方 ...

  3. Raid0创建

    实验步骤 步骤1: 确认硬盘 确认你的硬盘设备名. [root@servera ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 ...

  4. 免费的壁纸API

    最近在给EasyDesktop增加背景的功能, 考虑自己在服务器上部署壁纸, 维护成本比较高, 就找了几个免费的壁纸接口, 体验还不错, 这里简单记录一下. 1.Bing壁纸API 地址是: http ...

  5. selenium启动Chrome配置参数问题

    每次当selenium启动chrome浏览器的时候,chrome浏览器很干净,没有插件.没有收藏.没有历史记录,这是因为selenium在启动chrome时为了保证最快的运行效率,启动了一个裸浏览器, ...

  6. 记一些java里的数据结构

    0.Vector:过期的,被arraylist取代了 0.1Stack:也不建议使用 1.双向链表LinkedList:由list实现的接口类 2.队列Queue:操作为add remove elem ...

  7. mybatisplus实现一次多表联查+分页查询

    众所周知,mybatisplus非常好用,但是他不好用就不好用在不可以多表联查.在mybatisplusjoin中提供了联查的方法,那个参数我没看懂Orz 不过,历经千辛万苦,我通过xml终于写出来了 ...

  8. 解决SpringMVC/SpringBoot @RequestBody无法注入基本数据类型

    我们都知道SpringMVC使用 @RequestBody 注解可以接收请求content-type 为 application/json 格式的消息体.但是我们必须使用实体对象,Map或者直接用St ...

  9. Fiddler的工作原理

    Fiddler是位于客户端和服务器端中间的HTTP代理,是目前最常用的http抓包工具之一 . Fiddler抓取客户端和服务器之间的所有HTTP请求后进行分析.断点.过滤等操作. Fiddler可以 ...

  10. PHP 红包功能代码

    前段时间被问这个问题,最近有空就写写啦,还是挺有趣的 首先做下抢红包方法分类: 对于发红包的人来说,一共有大致3类(其他的我暂时没想到,有想到可以联系我呀~) 一.拼手气红包个数不定(完全看运气) 二 ...