参考:

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. 网易数帆实时数据湖 Arctic 的探索和实践

    作者 | 蔡芳芳 采访嘉宾 | 马进 网易数帆平台开发专家 数据中台也要从离线为主走向实时化,湖仓一体是第一步. 数据从离线到实时是当前一个很大的趋势,但要建设实时数据.应用实时数据还面临两个难题.首 ...

  2. MoneyPrinterPlus全面支持本地Ollama大模型

    MoneyPrinterPlus现在支持批量混剪,一键AI生成视频,一键批量发布短视频这些功能了. 之前支持的大模型是常用的云厂商,比如OpenAI,Azure,Kimi,Qianfan,Baichu ...

  3. PHP 使用非对称加密算法

    加密的类型: 在日常设计及开发中,为确保数据传输和数据存储的安全,可通过特定的算法,将数据明文加密成复杂的密文.目前主流加密手段大致可分为单向加密和双向加密. 单向加密:通过对数据进行摘要计算生成密文 ...

  4. PHP中substr() mb_substr() mb_struct()的区别和用法

    PHP substr() 函数可以分割文字,但要分割的文字如果包括中文字符往往会遇到问题,这时可以用mb_substr()/mb_strcut这个函 数,mb_substr() /mb_strcut的 ...

  5. webpack4.15.1 学习笔记(五) — 生产环境构建

    目录 生产环境构建 指定环境 生产环境构建 development和production的构建目标差异很大.dev中,需要具有实时重新加载或HMR能力的 source map 和 server.而在p ...

  6. Windows11下使用VcXsrv+xfce4实现图形化窗口

    通过 sudo apt-get install xfce4-terminal sudo apt-get install xfce4 sudo service dbus restart 来安装所需要的软 ...

  7. Python 阿里云OSS文件上传下载与文件删除及检索示例

    阿里云OSS文件上传下载与文件删除及检索示例 实践环境 运行环境: Python 3.5.4 CentOS Linux release 7.4.1708 (Core)/Win10 需要安装以下类库: ...

  8. RHCA rh442 007 hugetlbfs strace命令追踪 脏页设置 内存分配

    内存管理 虚拟内存 --- 物理内存 应用程序申请虚拟内存 --- RAM + SWAP (真正主板上的设备) 他们之间有一张映射表 page table 页表 PTE: 页表条目 虚拟内存和物理内存 ...

  9. python global变量作用域

    python变量作用域 var1 = 123 def func(): var1 = 456 print(var1) func() #456 print(var1) #123 ============= ...

  10. Python和RPA网页自动化-发送邮件

    以163邮箱为例,分别使用Python和RPA网页自动化发送邮件到指定邮箱 其中2个方法都需要用到163邮箱授权码,开启IMAP/SMTP服务即可得到授权码(POP3/SMTP服务不用开启) 1.py ...