在sqlserver2005之前,要实现递归功能比较麻烦,比如可能会要用到临时表与while语句来循环。自sqlserver2005之后,新增了with as功能语法,即 公用表达式(CTE),让递归实现起来变的简单了。

本章我们主要演示如何利用with as功能实现一个简单的递归功能。
在这之前先看一下cte的语法:

[ WITH <common_table_expression > [ ,...n ] ]
<common_table_expression >::=
        expression_name [ ( column_name [ ,...n ] ) ]
    AS
        ( CTE_query_definition )

参数说明
expression_name:
公用表表达式的有效标识符。 expression_name 必须与在同一 WITH <common_table_expression > 子句中定义的任何其他公用表表达式的名称不同,但 expression_name 可以与基表或基视图的名称相同。在查询中对 expression_name 的任何引用都会使用公用表表达式,而不使用基对象。

column_name:
在公用表表达式中指定列名。在一个 CTE 定义中不允许出现重复的名称。指定的列名数必须与CTE_query_definition结果集中列数匹配。只有在查询定义中为所有结果列都提供了不同的名称时,列名称列表才是可选的。

CTE_query_definition:
指定一个其结果集填充公用表表达式的 SELECT 语句。除了 CTE 不能定义另一个 CTE 以外,CTE_query_definition的 SELECT 语句必须满足与创建视图时相同的要求。
如果定义了多个 CTE_query_definition,则这些查询定义必须用下列一个集合运算符联接起来:UNION ALL、UNION、EXCEPT 或 INTERSECT。

--开始实例演示--

先创建一个仓库表,表名为Storage_Depository,该表有三个字段:DID(仓库编号),DName(仓库名称),PID(父仓库编号).
通过这样一个简单表,就可以将所有仓库信息,通过DID与PID字段来创建一个树型结构。
创建表的sql语句:

Create table Storage_Depository
(
DID varchar(50) not null primary key,
DName varchar(50) not null,
PID varchar(50) null
)

然后往该表插入演示数据:

insert into Storage_Depository(DID,DName,PID) 
select 'A','A仓库',null 
union all
select 'A-1','A-1仓库','A' 
union all
select 'A-2','A-2仓库','A' 
union all
select 'A-1-1','A-1-1仓库','A-1' 
union all
select 'B','B仓库',null 

从上面的数据可以看的出来,A的子仓为A-1与A-2仓,而A-1-1为A-1的子仓,B仓是一个独立的仓库,与A仓平级。
下面,我们通过with as功能,查出A仓下面的所有子仓:

with w_Storage_Depository as
(
select DID,DName,PID from Storage_Depository where DID='A'
union all
select A.DID,A.DName,A.PID from Storage_Depository A,w_Storage_Depository B where A.PID=B.DID
)
select * from w_Storage_Depository

代码很简短,也非常容易让人理解.

反过来,比如我们要查出A-1-1仓的所有上级仓,稍稍改一下上面的sql语句就可以了:

with w_Storage_Depository as
(
select DID,DName,PID from Storage_Depository where DID='A-1-1'
union all
select A.DID,A.DName,A.PID from Storage_Depository A,
w_Storage_Depository B where A.DID=B.PID
)
select * from w_Storage_Depository
 
http://www.lmwlove.com/ac/ID748

在sql server中利用with as实现递归功能的更多相关文章

  1. 模拟实现SQL Server中的datepart(week,date)的功能

    本文目录列表: 1.为什么要模拟实现datepart(week,date)的功能 2.具体实现思路 3.T-SQL代码实现逻辑 4.总结语 5.参考清单列表   1.为什么要模拟实现datepart( ...

  2. SQL Server中利用正则表达式替换字符串

    --如果存在则删除原有函数  IF OBJECT_ID(N'dbo.RegexReplace') IS NOT NULL       DROP FUNCTION dbo.RegexReplace  G ...

  3. Sql Server中利用ISNULL方法判断数字并预设值

    1.ISNULL方法有两个参数,ISNULL(a,b),表达式含义为如果a为NULL,则设置该字段内容为b. 例如 table tab id sum 1 1 2 null select t.id,is ...

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

    本文出处:http://www.cnblogs.com/wy123/p/5960825.html 我们在做开发的时候,有时候会需要一些帮助数据,必须需要连续的数字,连续间隔的时间点,连续的季度日期等等 ...

  5. SQL Server中提前找到隐式转换提升性能的办法

        http://www.cnblogs.com/shanksgao/p/4254942.html 高兄这篇文章很好的谈论了由于数据隐式转换造成执行计划不准确,从而造成了死锁.那如果在事情出现之前 ...

  6. SQL Server中In-Flight日志究竟是多少

        在SQL Server中,利用日志的WAL来保证关系数据库的持久性,但由于硬盘的特性,不可能使得每生成一条日志,就直接向磁盘写一次,因此日志会被缓存起来,到一定数据量才会写入磁盘.这部分已经生 ...

  7. 浅谈SQL Server中的三种物理连接操作

    简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge J ...

  8. 谈一谈SQL Server中的执行计划缓存(上)

    简介 我们平时所写的SQL语句本质只是获取数据的逻辑,而不是获取数据的物理路径.当我们写的SQL语句传到SQL Server的时候,查询分析器会将语句依次进行解析(Parse).绑定(Bind).查询 ...

  9. SQL Server中的“最大并行度”的配置建议

    SQL Server中的最大并行度(max degree of parallelism)如何设置呢? 设置max degree of parallelism有什么好的建议和指导方针呢?在微软官方文档R ...

随机推荐

  1. angular2开发01

    // */ // ]]> angular2开发01 1. angular2 开发准备 1.1. 安装node 1.2. 安装npm 1.3. 运行qickStart 1 angular2 开发准 ...

  2. Lua学习----Lua基础数据类型

    前言 Lua有6中数据类型,分别是nil(空).boolean(布尔).number(数字).string(字符).table(表).function(函数) 在Lua中可以使用type函数来返回一个 ...

  3. 【学】AngularJS日记(2)

    数组循环放到新生成的li中 <ul ng-init="arr=[12,5,6,394,344]"> <li ng-repeat="item in arr ...

  4. org.apache.catalina.LifecycleException tomcat 启动 maven 处处都是坑!!!

    问题1:tomcat不识别maven工程解决办法:project右击->Properties->Project Facets,选择Dynamic Web Module及其版本(tomcat ...

  5. 在sql脚本中获取变量中的查询结果

    )--变量 ) set @itemValue='select @a=getdate()'--赋值 exec sp_executesql @itemValue,N'@a nvarchar(max) ou ...

  6. java 事件监听 - 键盘

    java 事件监听 - 键盘 //事件监听 //键盘事件监听,写了一个小案例,按上下左右,改变圆形的位置,圆形可以移动 import java.awt.*; import javax.swing.*; ...

  7. Winform软件,不要在线程里操作UI

    对于Winform软件,不要在线程里操作UI,不要相信:StartForm.CheckForIllegalCrossThreadCalls = false; 于是,把所有的代码都改成主线程委托调用的方 ...

  8. linux mint 崩溃

    换完linux mint 今天突然崩溃了.出现如下错误 因为是双屏.一个屏幕显示一般,这么不重要.搜了一下,找到解决方案 解决办法 ctrl+atl+f1 login sudo apt-get ins ...

  9. ASCIITable: 演示 Arduino 串口输出的进阶功能

    原文地址 - https://www.arduino.cc/en/Tutorial/ASCIITable ASCII字符表 本例展示了高级的串口打印功能,通过本功能可以在Arduino软件(IDE)的 ...

  10. 【原】redis插件安装

    wget -c https://github.com/nicolasff/phpredis/archive/2.2.4.tar.gz -O phpredis-2.2.4.tar.gz tar xzf ...