SQL点点滴滴_公用表表达式(CTE)递归的生成帮助数据
本文的作者辛苦了,版权问题特声明本文出处:http://www.cnblogs.com/wy123/p/5960825.html
工作有时候会需要一些帮助数据,必须需要连续的数字,连续间隔的时间点,连续的季度日期等等。常见很多人利用master库的spt_values系统表。
比如下面这个(没截完,结果是0-2047)

这样也可以使用,但是感觉不够灵活,一不是随便一个账号都可以访问master数据库的,另外一个这里面也只有这么一个连续的数字了,想要别的结果集就不太弄。
类似数据可以用公用表表达式CTE的递归来生成,比如上述的0-2047的结果集

;with GenerateHelpData
as
(
select 0 as id
union all
select id+1 from GenerateHelpData where id<2047
)
select id from GenerateHelpData option (maxrecursion 2047);

可以直接让CTE参数逻辑运算,也可以生成临时表,达到多次重用的目的。
1、生成连续数字(当然数字的起始值,间隔值都可以自定义)

--生成连续数字
;with GenerateHelpData
as
(
select 0 as id
union all
select id+1 from GenerateHelpData where id<2047
)
select id from GenerateHelpData option (maxrecursion 2047);


2、CTE递归生成连续日期

--生成连续日期
;with GenerateHelpData
as
(
select cast('2016-10-01' as date) as [Date]
union all
select DATEADD(D,1,[Date]) from GenerateHelpData where [Date]<'2017-01-01'
)
select [Date] from GenerateHelpData;


3、生成连续间隔的时间点
有时候一些统计需要按照一个小时或者半个小时之类的时间间隔做组合,比如统计某天内没半个小时的小时数据等等

--生成连续间隔的时间点
;with GenerateHelpData
as
(
select 1 as id, cast('00:00:00' as time(0)) as timeSection
union all
select id+1 as id, cast(dateadd(mi,30,timeSection) as time(0)) as timeSection
from GenerateHelpData where id<49
)
select * from GenerateHelpData


当然这里就可以非常灵活了,更骚一点的变形

--更骚一点的变形
;with GenerateHelpData
as
(
select 1 as id, cast('00:00:00' as time(0)) as timeSection
union all
select id+1 as id, cast(dateadd(mi,30,timeSection) as time(0)) as timeSection
from GenerateHelpData where id<49
)
select
A.timeSection as timeSectionFrom,
B.timeSection as timeSectionTo,
cast(A.timeSection as varchar(10))+'~'+cast(B.timeSection as varchar(10)) as timeSection
from GenerateHelpData A inner join GenerateHelpData B on A.id= B.id-1


4、生成连续季度的最后一天

DECLARE
@begin_date date = '2014-12-31',
@end_date date = '2016-12-31'
;with GenerateHelpData as
(
select
CAST( CASE
WHEN RIGHT(@begin_date,5)='12-30'
THEN DATEADD(DAY,1,@begin_date)
ELSE @begin_date
END AS DATE)
AS EndingDate
UNION ALL
SELECT
CASE WHEN RIGHT(DATEADD(QQ,1,EndingDate),5)='12-30'
THEN DATEADD(DAY,1,DATEADD(QQ,1,EndingDate))
ELSE DATEADD(QQ,1,EndingDate)
END AS EndingDate
from GenerateHelpData where EndingDate< @end_date
)
select * from GenerateHelpData


通过变形可以生成两个日期间隔之间的的数据

DECLARE
@begin_date date = '2014-12-31',
@end_date date = '2016-12-31'
;with GenerateHelpData as
(
select 1 as id ,
CAST( CASE
WHEN RIGHT(@begin_date,5)='12-30'
THEN DATEADD(DAY,1,@begin_date)
ELSE @begin_date
END AS DATE)
AS EndingDate
UNION ALL
SELECT id+1 as id,
CASE WHEN RIGHT(DATEADD(QQ,1,EndingDate),5)='12-30'
THEN DATEADD(DAY,1,DATEADD(QQ,1,EndingDate))
ELSE DATEADD(QQ,1,EndingDate)
END AS EndingDate
from GenerateHelpData where EndingDate< @end_date
)
select
A.EndingDate as DateFrom,
B.EndingDate as DateTo,
cast(A.EndingDate as varchar(10))+'~'+cast(B.EndingDate as varchar(10)) as timeSection
from GenerateHelpData A inner join GenerateHelpData B on A.id= B.id-1


需要注意的是:
1、CTE递归的默认次数是100,如果不指定递归次数(option (maxrecursion N);),超出默认最大递归次数之后会报错。

2、指定了最大递归次数以后,超出最大递归次数也会报错。

总结:本文演示了几种常用的根据CTE递归生成帮助数据的情况,如果需要帮助数据,可以根据CTE的递归特性做灵活处理。
SQL点点滴滴_公用表表达式(CTE)递归的生成帮助数据的更多相关文章
- SQL Server中公用表表达式 CTE 递归的生成帮助数据,以及递归的典型应用
本文出处:http://www.cnblogs.com/wy123/p/5960825.html 我们在做开发的时候,有时候会需要一些帮助数据,必须需要连续的数字,连续间隔的时间点,连续的季度日期等等 ...
- sql server使用公用表表达式CTE通过递归方式编写通用函数自动生成连续数字和日期
问题:在数据库脚本开发中,有时需要生成一堆连续数字或者日期,例如yearly report就需要连续数字做年份,例如daily report就需要生成一定时间范围内的每一天日期.而自带的系统表mast ...
- SQL Server温故系列(3):SQL 子查询 & 公用表表达式 CTE
1.子查询 Subqueries 1.1.单行子查询 1.2.多行子查询 1.3.相关子查询 1.4.嵌套子查询 1.5.子查询小结及性能问题 2.公用表表达式 CTE 2.1.普通公用表表达式 2. ...
- 详解公用表表达式(CTE)
简介 对于SELECT查询语句来说,通常情况下,为了使T-SQL代码更加简洁和可读,在一个查询中引用另外的结果集都是通过视图而不是子查询来进行分解的.但是,视图是作为系统对象存在数据库中,那对于结果集 ...
- T-SQL查询进阶--详解公用表表达式(CTE)
简介 对于SELECT查询语句来说,通常情况下,为了使T-SQL代码更加简洁和可读,在一个查询中引用另外的结果集都是通过视图而不是子查询来进行分解的. 但是,视图是作为系统对象存在数据库中,那对于结果 ...
- SQL Server 公用表表达式(CTE)实现递归
公用表表达式简介: 公用表表达式 (CTE) 可以认为是在单个 SELECT.INSERT.UPDATE.DELETE 或 CREATE VIEW 语句的执行范围内定义的临时结果集.CTE 与派生表类 ...
- SQL Server 公用表表达式(CTE)实现递归的方法
公用表表达式简介: 公用表表达式 (CTE) 可以认为是在单个 SELECT.INSERT.UPDATE.DELETE 或 CREATE VIEW 语句的执行范围内定义的临时结果集.CTE 与派生表类 ...
- 公用表表达式 (CTE)、递归、所有子节点、sqlserver
指定临时命名的结果集,这些结果集称为公用表表达式 (CTE).公用表表达式可以包括对自身的引用.这种表达式称为递归公用表表达式. 对于递归公用表达式来说,实现原理也是相同的,同样需要在语句中定义两部分 ...
- SQL Server进阶(六)表表达式--派生表、公用表表达式(CTE)、视图和内联表值函数
概述 表表达式是一种命名的查询表达式,代表一个有效地关系表.可以像其他表一样,在数据处理中使用表表达式. SQL Server支持四种类型的表表达式:派生表,公用表表达式,视图和内联表值函数. 为什么 ...
随机推荐
- Python中utf-8与utf-8-sig两种编码格式的区别
As UTF-8 is an 8-bit encoding no BOM is required and anyU+FEFF character in the decoded Unicode stri ...
- java调用svnkit工具类上传本地文件到svn服务器
package org.jenkinsci.plugins.svn.upload.step; import java.io.*; import org.tmatesoft.svn.core.SVNCo ...
- C 扩展库 - mysql API
MySQL API C API Data Structures MYSQL This structure represents handler for one database connection. ...
- a+b+c的N次方展开
今天在给儿子看笔记本上的照片的时候,偶然发现了2009年手绘的一张a+b+c的N次方展开图,故写下面的博客以记之,为年轻时代的我点个赞! 20年前的我,一个充满激情的且富有专注力的数学发烧友! 10年 ...
- mysql去除重复记录案例
例1,表中有主键(可唯一标识的字段),且该字段为数字类型 1 测试数据 /* 表结构 */ DROP TABLE IF EXISTS `t1`; CREATE TABLE IF NOT EXISTS ...
- TCP/IP的基本概念知识
1.分层 TCP/IP通常是被分成四层协议系统的,应用层(Telnet.FTP和Email等).运输层(TCP.UDP).网络层(IP.ICMP.IGMP等)和链路层(设备驱动程序),每一层各 ...
- cursor : 普通,带参,可更新的游标。使用游标遍历时,强烈建议用for循环!!!
cursor: 源数据表account中仅有两条记录: 如果输出在判断前,则出错,将最后一条记录输出两次,如下: 所以,一定要先判断notfound再输出结果: exit when (c%notfou ...
- Common class for judge IPV6 or IPV4
import java.util.regex.Pattern; import org.apache.http.annotation.Immutable; /** * A collection of u ...
- SQL Server 导入excel时“该值违反了该列的完整性约束”错误
SQL Server 导入excel时“该值违反了该列的完整性约束”错误 这个问题看似高大上,仔细分析了一下,ID列怎么会有重复呢? 原来是有很多空行呀!!! 所以导入excel时一定要注意空行的问题 ...
- Java常用的排序算法三
Merge Sort :归并排序:用递归的思想,分解成单个元素的排序,在归并 代码: import java.util.*; public class MergeSort { public stati ...