原文: SQL Server中公用表表达式 CTE 递归的生成帮助数据,以及递归的典型应用

本文出处:http://www.cnblogs.com/wy123/p/5960825.html

我们在做开发的时候,有时候会需要一些帮助数据,必须需要连续的数字,连续间隔的时间点,连续的季度日期等等
常见很多人利用master库的spt_values系统表,这个当然没有问题

比如下面这个(没截完,结果是0-2047)

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

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

可以直接让CTE参数逻辑运算,也可以生成临时表,达到多次重用的目的,这样感觉是不是也很清爽?

1,生成连续数字(当然数字的起始值,间隔值都可以自定义)

--生成连续数字
;with GenerateHelpData
as
(select 0 as idunion allselect 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 allselect 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 timeSectionunion allselect 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 timeSectionunion allselect 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 EndingDateUNION ALLSELECT     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 EndingDatefrom 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 EndingDateUNION ALLSELECT     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 EndingDatefrom 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

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

——————————————递归原本很容易使用,本文原本是说用递归生成帮助数据的,有朋友问到递归本身的使用,那就再补充一个DEMO吧———————————————————

补充园友的一个实际应用-20161119

测试数据:

create table ProuctInfo
(Id INT,ParentId INT,ProuctName VARCHAR(50)
)INSERT INTO ProuctInfo VALUES (1,0,'镜片')
INSERT INTO ProuctInfo VALUES (2,0,'镜架')
INSERT INTO ProuctInfo VALUES (101,1,'高级镜片')
INSERT INTO ProuctInfo VALUES (102,1,'普通镜片')
INSERT INTO ProuctInfo VALUES (201,2,'高级镜架')
INSERT INTO ProuctInfo VALUES (202,2,'普通镜架')INSERT INTO ProuctInfo VALUES (1001,101,'高级镜片1')
INSERT INTO ProuctInfo VALUES (1002,102,'普通镜片2')
INSERT INTO ProuctInfo VALUES (2001,201,'高级镜架1')
INSERT INTO ProuctInfo VALUES (2002,202,'普通镜架2')

原始数据的样子,很普通

创建一个函数,获取当前节点的父节点信息

CREATE FUNCTION dbo.FnGetParentInfo(@id int)
returns varchar(max)
as
begindeclare @name varchar(max)--查询某一个节点的所有父节点
;with SubTab
as
(select [ID],[ParentID], cast(ProuctName as varchar(200)) as ProuctNamefrom ProuctInfo WHERE Id = @idunion allselect a.[ID],a.[ParentID],cast(a.ProuctName+'--->'+b.ProuctName as varchar(200)) as ProuctNamefrom ProuctInfo a,SubTab bwhere a.[ID]=b.[ParentID]
)
select @name = ProuctName from SubTab  where ParentId = 0 return @name
end

实际效果:

  

  

 总结:本文演示了几种常用的根据CTE递归生成帮助数据的情况,如果需要帮助数据,可以根据CTE的递归特性做灵活处理。

SQL Server中公用表表达式 CTE 递归的生成帮助数据,以及递归的典型应用相关推荐

  1. 在Sql Server 2005使用公用表表达式CTE简化复杂的查询语句

    公用表表达式CTE是Sql Server 2005引入的一种新的表表达式.CTE在许多方面都类似于派生表.逻辑上CTE是一个临时结果集,它仅仅存在于它发生的语句中.您可以在SELECT.INSERT. ...

  2. T-SQL查询进阶--详解公用表表达式(CTE)

    简介 对于SELECT查询语句来说,通常情况下,为了使T-SQL代码更加简洁和可读,在一个查询中引用另外的结果集都是通过视图而不是子查询来进行分解的.但是,视图是作为系统对象存在数据库中,那对于结果集 ...

  3. 详解公用表表达式(CTE)

    简介 对于SELECT查询语句来说,通常情况下,为了使T-SQL代码更加简洁和可读,在一个查询中引用另外的结果集都是通过视图而不是子查询来进行分解的.但是,视图是作为系统对象存在数据库中,那对于结果集 ...

  4. 公用表表达式(CTE)WITH:树型查询、更新

    转自http://msdn.microsoft.com/zh-cn/library/ms175972(SQL.100).aspx 指定临时命名的结果集,这些结果集称为公用表表达式 (CTE). 语法: ...

  5. mysql cte 语法,mysql8 公用表表达式CTE的使用方法实例分析

    本文实例讲述了mysql8 公用表表达式cte的使用方法.分享给大家供大家参考,具体如下: 公用表表达式cte就是命名的临时结果集,作用范围是当前语句. 说白点你可以理解成一个可以复用的子查询,当然跟 ...

  6. cte mysql_mysql8 公用表表达式CTE的使用

    公用表表达式CTE就是命名的临时结果集,作用范围是当前语句. 说白点你可以理解成一个可以复用的子查询,当然跟子查询还是有点区别的,CTE可以引用其他CTE,但子查询不能引用其他子查询. 一.cte的语 ...

  7. mysql cte_mysql8 公用表表达式CTE的使用方法实例分析

    本文实例讲述了mysql8 公用表表达式CTE的使用方法.分享给大家供大家参考,具体如下: 公用表表达式CTE就是命名的临时结果集,作用范围是当前语句. 说白点你可以理解成一个可以复用的子查询,当然跟 ...

  8. Sql Server中判断表或者数据库是否存在

    SQL Server中判断数据库是否存在: 法(一): select * From master.dbo.sysdatabases where name='数据库名' 法(二): if db_id(' ...

  9. SQL Server中的表变量

    In this article, we will explore the table variable in SQL Server with various examples and we will ...

最新文章

  1. EM算法理解的九层境界
  2. system.err android.os.NetworkOnmainThreadException 错误解决办法
  3. 安装cv2(opencv-python)遇到的问题
  4. 输出任意一元二次函数的结果值
  5. linux 简单Shell程序设计,利用linux下的c语言编程来简单的实现一个shell功能实现!...
  6. deb包如何改支持12系统_对一个deb包的解压、修改、重新打包全过程方法
  7. (转) SpringBoot接入两套kafka集群
  8. node源码详解(五)
  9. Knight Moves(信息学奥赛一本通-T1450)
  10. 2014第3周六升级win8.1
  11. C语言 —— 回调函数
  12. aws 亚马逊_Amazon AWS Rekognition教程
  13. 计算机全盘搜索功能不见了,win7搜索功能不见了两种恢复方法(图文)
  14. [HDU 5755] Gambler Bo (高斯消元)
  15. mysql删除多表视图数据,【杂谈】怎样删除mysql数据表视图中数据
  16. iMessage群发,苹果群发技术开源
  17. pos 机 gd32f103 midi设备
  18. 118 以太坊 ethereum hardhat :编译 artifacts
  19. 批量删除svn隐藏文件
  20. 汇川PLC如何连接工业网关实现远程编程和远程上下载程序?

热门文章

  1. 机器人系统的基本概念及外部模型参数详解
  2. Swift语言针对机器学习
  3. WordPress自带TinyMCE编辑器增强技巧大全
  4. 2023最新酷酷资源社同款Xiuno模板源码/知乎蓝魔改版源码+附完整全套插件
  5. CDA Level Ⅲ 模拟题(二)
  6. html实现鼠标跟随,html5实现鼠标跟随
  7. PHP的页面布局怎样设计
  8. 分形图java_数字的美丽——分形图形
  9. 安利一个自动求导网站
  10. AngularJS 表达式