标签:
非递归公用表表达式是查询结果仅仅一次性返回一个结果集用于外部查询调用。并不在其定义的语句中调用其自身的CTE。非递归公用表表达式的使用方式和视图以及子查询一致。
比如一个简单的非递归公用表表达式
递归公用表表达式指的是在CTE内的语句中调用其自身的CTE。
对于递归公用表达式来说,实现原理也是相同的,同样需要在语句中定义两部分:
在SQL这两部分通过UNION ALL连接结果集进行返回:
比如:
先建一张表栏目表如下,栏目Id,栏目名称,栏目的父栏目。
现在使用CTE查询其每个栏目是第几层栏目的代码如下:
WITH COL_CTE(Id,Name,ParentId,tLevel ) AS ( --基本语句 SELECT Id,Name,ParentId,0 AS tLevel FROM Col WHERE ParentId = 0 UNION ALL --递归语句 SELECT c.Id,c.Name,c.ParentId,ce.tLevel+1 AS tLevel FROM COL as c INNER JOIN COL_CTE AS ce --递归调用 ON c.ParentId = ce.Id ) SELECT * FROM COL_CTE
输出结果如下:
0表示顶级栏目。1就是1级栏目。语法非常优雅。就一个SELECT * FRON COL_CTE。这正是CTE强大的地方,但是,这要有约束,否则如果无限制递归可以会消耗掉非常多的系统资源。还可以通过OPTION(MAXRECURSION n) 限制递归的最大次数。
如将上面的查询语法改为:
WITH COL_CTE(Id,Name,ParentId,tLevel ) AS ( --基本语句 SELECT Id,Name,ParentId,0 AS tLevel FROM Col WHERE ParentId = 0 UNION ALL --递归语句 SELECT c.Id,c.Name,c.ParentId,ce.tLevel+1 AS tLevel FROM COL as c INNER JOIN COL_CTE AS ce ON c.ParentId = ce.Id ) SELECT * FROM COL_CTE OPTION(MAXRECURSION 2) --指定最大递归次数为2
with开始前有时候建议加‘;‘符号结束前面的语句。因为with在其他地方有他的含义,加以区别。
CTE是一种十分优雅的存在。CTE所带来最大的好处是代码可读性的提升,这是良好代码的必须品质之一。使用递归CTE可以更加轻松愉快的用优雅简洁的方式实现复杂的查询。
标签:
原文地址:http://www.cnblogs.com/PointBreak/p/5656921.html