Sql Server系列:通用表表达式CTE
1 CTE语法WITH关键字
通用表表达式(Common Table Express, CTE),将派生表定义在查询的最前面。要使用CTE开始创建一个查询,可以使用WITH关键字。
CTE语法:
WITH <expression_name> [(column_name [,...n])]
AS
( CTE_query_definition)
[, <another_expression>]
<query>
首先为CTE提供一个名称,该名称类似于用于派生表的别名。然后可以提供CTE将返回的列名列表;如果CTE指定了它的所有返回列,则这是可选操作。最后,在圆括号中添加CTE查询的定义,最后添加使用CTE的主查询。
WITH关键字之前的语句必须使用分号(;)结束。
示例
WITH cte
AS
(
SELECT * FROM [dbo].[Product]
) SELECT [ProductID],[ProductCode],[ProductName],[UnitPrice] FROM cte
连接查询示例
WITH ProductCTE([CategoryID], [ProductsCount])
AS
(
SELECT [CategoryID],COUNT(1)
FROM [dbo].[Product]
GROUP BY [CategoryID]
) SELECT c.[CategoryID],c.[CategoryName], cte.[ProductsCount]
FROM [dbo].[Category] c
INNER JOIN ProductCTE cte
ON c.[CategoryID] = cte.[CategoryID]
ORDER BY cte.[ProductsCount]
2 使用多个CTE
使用WITH开始语句可以定义多个CTE,不需要重复使用WITH关键字,每一个CTE可以使用在该语句中已经定义的任意CTE(作为其定义的一部分)。
WITH CategoryCTE
AS
(
SELECT * FROM [dbo].[Category]
),ProductCTE
AS
(
SELECT p.*,cte.[CategoryName] FROM [dbo].[Product] p
INNER JOIN CategoryCTE cte
ON p.[CategoryID] = cte.[CategoryID]
) SELECT * FROM ProductCTE
3 递归CTE
递归公用表表达式是在CTE内的语句中调用其自身的CTE。
示例
WITH cte([CategoryID],[CategoryName],[ParentID],[Level])
AS
(
-- 查询语句
SELECT [CategoryID],[CategoryName],[ParentID],1 AS [Level] FROM [dbo].[Category]
WHERE [ParentID] IS NULL
UNION ALL
-- 递归语句
SELECT c.[CategoryID],c.[CategoryName],c.[ParentID], cte.[Level] + 1
FROM [dbo].[Category] c
INNER JOIN cte
ON c.[CategoryID] = cte.[ParentID]
) SELECT [CategoryID],[CategoryName],[ParentID],[Level] FROM cte
限制递归层次
WITH cte([CategoryID],[CategoryName],[ParentID],[Level])
AS
(
-- 查询语句
SELECT [CategoryID],[CategoryName],[ParentID],1 AS [Level] FROM [dbo].[Category]
WHERE [ParentID] IS NULL
UNION ALL
-- 递归语句
SELECT c.[CategoryID],c.[CategoryName],c.[ParentID], cte.[Level] + 1
FROM [dbo].[Category] c
INNER JOIN cte
ON c.[CategoryID] = cte.[ParentID]
) SELECT [CategoryID],[CategoryName],[ParentID],[Level] FROM cte
OPTION(MAXRECURSION 2)
Where过滤递归结果数据层次
WITH cte([CategoryID],[CategoryName],[ParentID],[Level])
AS
(
-- 查询语句
SELECT [CategoryID],[CategoryName],[ParentID],1 FROM [dbo].[Category]
WHERE [ParentID] IS NULL
UNION ALL
-- 递归语句
SELECT c.[CategoryID],c.[CategoryName],c.[ParentID], [Level] + 1
FROM [dbo].[Category] c
INNER JOIN cte
ON c.[CategoryID] = cte.[ParentID]
) SELECT [CategoryID],[CategoryName],[ParentID],[Level] FROM cte
WHERE cte.[Level] <= 3
Sql Server系列:通用表表达式CTE的更多相关文章
- sql server使用公用表表达式CTE通过递归方式编写通用函数自动生成连续数字和日期
问题:在数据库脚本开发中,有时需要生成一堆连续数字或者日期,例如yearly report就需要连续数字做年份,例如daily report就需要生成一定时间范围内的每一天日期.而自带的系统表mast ...
- SQL Server CET 通用表表达式 之 精典递归
SQL2005 Common Table Expressions(CET)即通用表表达式. SQLSERVER CET递归使用案例: 1.普通案例 表结构如下: ;WITH cet_depart ...
- SQL Server中公用表表达式 CTE 递归的生成帮助数据,以及递归的典型应用
本文出处:http://www.cnblogs.com/wy123/p/5960825.html 我们在做开发的时候,有时候会需要一些帮助数据,必须需要连续的数字,连续间隔的时间点,连续的季度日期等等 ...
- SQL Server温故系列(3):SQL 子查询 & 公用表表达式 CTE
1.子查询 Subqueries 1.1.单行子查询 1.2.多行子查询 1.3.相关子查询 1.4.嵌套子查询 1.5.子查询小结及性能问题 2.公用表表达式 CTE 2.1.普通公用表表达式 2. ...
- sql server编写简洁四则运算表达式脚本实现计算批次功能(C#等其它编程语言也能直接用此通用表达式)
问题: 在数据库编程开发中,有时会遇到数据量比较大的情况,如果直接大批量进行添加数据.修改数据.删除数据,就会是比较大的事务,事务日志也比较大,耗时久的话会对正常操作造成一定的阻塞.虽不至于达到删库跑 ...
- SQLServer中的CTE(Common Table Expression)通用表表达式使用详解
概述 我们经常会编写由基本的 SELECT/FROM/WHERE 类型的语句派生而来的复杂 SQL 语句.其中一种方案是需要编写在 FROM 子句内使用派生表(也称为内联视图)的 Transact-S ...
- SQLServer中的CTE通用表表达式
开发人员正在研发的许多项目都涉及编写由基本的 SELECT/FROM/WHERE 类型的语句派生而来的复杂 SQL 语句.其中一种情形是需要编写在 FROM 子句内使用派生表(也称为内联视图)的 Tr ...
- SQL Server系列目录
一.SQL Server基础部分 1 数据库概念及规范化设计 1.1 数据库物理模式设计 1.2 Microsoft SQL Server Management Studio模板资源管理器 2 数据 ...
- 公用表表达式 (CTE)、递归、所有子节点、sqlserver
指定临时命名的结果集,这些结果集称为公用表表达式 (CTE).公用表表达式可以包括对自身的引用.这种表达式称为递归公用表表达式. 对于递归公用表达式来说,实现原理也是相同的,同样需要在语句中定义两部分 ...
随机推荐
- 【原】iOS学习之PINCache第三方缓存框架
在项目中总是需要缓存一些网络请求数据以减轻服务器压力,业内也有许多优秀的开源的解决方案.通常的缓存方案都是由内存缓存和磁盘缓存组成的,内存缓存速度快容量小,磁盘缓存容量大速度慢可持久化. 1.PINC ...
- 【BZOJ1857】[Scoi2010]传送带 三分法
三分套三分,挺神奇的...每次找到,每个传送带的上下两个三等分点,下面那个小,则一定有更优的在中间. #include <iostream> #include <cstdio> ...
- lua的C库
在云风的ejoy2d里是没有dll和so之类的东西的, 所有的C扩展都是类似这样写的: int ejoy2d_shader(lua_State *L) { luaL_Reg l[] = { ...
- 关于MySQL 的LEFT JOIN ON的问题
今天在查询视图时,遇到了一个问题. 因为mysq不能嵌套select的子查询.所以我把子查询建成了视图b,主查询通过left join on关联视图b ,形成视图a. 由于视图b中也有left joi ...
- Linux Shell 编程中的特殊符号
一.井号 # 1.在脚本文件中对一行进行注释. 2.在引号和\符号后不是注释,只是#号本身: echo "12 # hehe" echo '12 # hehe' echo 12 \ ...
- java-sql注入攻击
注射式攻击的原理 SQL注射能使攻击者绕过认证机制,完全控制远程服务器上的数据库.SQL是结构化查询语言的简称,它是访问数据库的事实标准.目前,大多数Web应用都使用SQL数据库来存放应用程序的数据. ...
- android的EditText重新获取焦点问题
在android开发过程中关于EditText在setFocusable(false);后,当需要再次获得焦点输入时设置setFocusable(true);后还是无法获得焦点的问题: 解决办法: 对 ...
- C++ 编写DLL文件给易语言调用
摸索了两天了,终于解决了所有问题,在此跟大家分享. 需要三个文件,dll_demo.h.dll_demo.cpp.dll_dome.def 直接上代码: 头文件如下: #ifndef _DLL_DEM ...
- vector、list、deque三者比较
1.vector是一段连续的内存块,而deque是多个连续的内存块,list是所有数据元素分开保存,可以是任何两个元素都没有连续. 2.vector的查询性能最好,并且的末端增加数据也很好,除非它重新 ...
- DAO模型
DAO模型 前面我们在使用JDBC时解决的都是一些很简单的问题,例如登录,注册等等,所以有些例直接把代码写在了main方法中.这种写法很容易出现代码臃肿,耦合度高,不能模块化开发等诸多弊端,特别是将来 ...