在做数据库设计这块,很多时候表的数据模型就是典型的二叉树结构。

于是在查询数据的时候,就涉及到了数据的递归查询。
递归查询分为两种:1.从根节点查询自身以及所有的子节点;2.从子节点查询自身以及所有的父节点。
下面分别以Oracle 11g 数据库和MsSql 2008 数据库为例,来实现上述两种类型的递归查询
先建一张表
表名: TAdministrative
 字段名称  说明
 AdministrativeID  行政编号
 AdministrativePID  当前行政级别的上一行政级别编号
 AdministrativeName  当前行政级别名称
 AdministrativeRemark  当前行政级别备注
MsSql:
1.从根节点查询到子节点
----从根节点查向子节点
WITH CET_Administrative(AdministrativeID,AdministrativePID,AdministrativeName,AdministrativeRemark)
AS
(
----固定数据
SELECT AdministrativeID,AdministrativePID,AdministrativeName,AdministrativeRemark FROM TAdministrative WHERE AdministrativePID IS NULL
UNION ALL
----递归数据
SELECT T.AdministrativeID,T.AdministrativePID,
T.AdministrativeName,T.AdministrativeRemark
FROM TAdministrative T
INNER JOIN CET_Administrative ON CET_Administrative.AdministrativeID=T.AdministrativePID
)
 
SELECT AdministrativeID,AdministrativePID,AdministrativeName,AdministrativeRemark FROM CET_Administrative
OPTION (MAXRECURSION 0);
GO
 
2.然后是由子节点查询到根节点
WITH CET_Administrative(AdministrativeID,AdministrativePID,AdministrativeName,AdministrativeRemark)
AS
(
----固定数据
SELECT AdministrativeID,AdministrativePID,AdministrativeName,AdministrativeRemark FROM TAdministrative WHERE AdministrativeID = '25D8C293B5A448E9B821558A0AFDB0A2'
UNION ALL
----递归数据
SELECT T.AdministrativeID,T.AdministrativePID,
T.AdministrativeName,T.AdministrativeRemark
FROM TAdministrative T
INNER JOIN CET_Administrative ON CET_Administrative.AdministrativePID=T.AdministrativeID
)
 
SELECT AdministrativeID,AdministrativePID,AdministrativeName,AdministrativeRemark FROM CET_Administrative
OPTION (MAXRECURSION 0);
GO
 
Oracle:
1.从根节点到子节点:
SELECT AdministrativeID,AdministrativePID,AdministrativeName,AdministrativeRemark 
FROM TAdministrative START WITH AdministrativePID IS NULL 
CONNECT BY PRIOR AdministrativeID=AdministrativePID;
 
2.从子节点查询到根节点:
SELECT AdministrativeID,AdministrativePID,AdministrativeName,AdministrativeRemark 
FROM TAdministrative START WITH AdministrativeID ='25D8C293B5A448E9B821558A0AFDB0A2'
CONNECT BY PRIOR AdministrativePID=AdministrativeID;
 
两者从根节点到子节点的遍历方式不一样,Oracle是先序遍历,至于MsSql其实是迭代的一种实现。大家可以看看MSDN的CTE解释:http://msdn.microsoft.com/zh-cn/library/ms186243(v=SQL.90).aspx
 
MsSql的语法如下:

WITH cte_name ( column_name [,...n] )

AS

(

CTE_query_definition –- Anchor member is defined.

UNION ALL

CTE_query_definition –- Recursive member is defined referencing cte_name.

)

-- Statement using the CTE

SELECT *

FROM cte_name

递归执行的语义如下:

  1. 将 CTE 表达式拆分为定位点成员和递归成员。
  2. 运行定位点成员,创建第一个调用或基准结果集 (T0)。
  3. 运行递归成员,将 Ti 作为输入,将 Ti+1 作为输出。
  4. 重复步骤 3,直到返回空集。
  5. 返回结果集。这是对 T0 到 Tn 执行 UNION ALL 的结果。
Anchor member is defined. 这个位置查询的是数据集T0,然后Recursive member is defined referencing cte_name这个位置开始讲T0的数据代入其中根据条件再做计算得到T1,依次代入直到得带Ti为空集结束(当然,不是无限制的递归,读者自己看msdn的解释)。
 
oracle语法如下:
SELECT ... FROM TABLENAME START WITH COND1 CONNECT BY COND2 WHERE COND3;
START WITH 是起始条件,就是说第一条数据时从哪里开始的
CONNECT BY 是连接条件,即其实数据集和下一个数据集的联系,上面是 START WITH AdministrativeID ='25D8C293B5A448E9B821558A0AFDB0A2' CONNECT BY PRIOR AdministrativePID=AdministrativeID; 即由子节点查询到根节点时,先得到起始子节点,然后连接条件 AdministrativePID=AdministrativeID 等号左边的是子节点的父节点编号,右边是父节编号,即找到“当前子节点的父节点编号=父节点编号”的集合。

SqlServer CTE 递归查询 Oracle递归查询的更多相关文章

  1. 【转载】Oracle递归查询:使用prior实现树操作【本文出自叶德华博客】

    本文标题:Oracle递归查询:使用prior实现树操作 本文链接:http://yedward.net/?id=41 本文版权归作者所有,欢迎转载,转载请以文字链接的形式注明文章出处. Oracle ...

  2. 【2016-11-7】【坚持学习】【Day22】【Oracle 递归查询】

    直接在oracle 递归查询语句 select * from groups start with id=:DeptId connect by prior superiorid =id 往下找 sele ...

  3. Oracle递归查询start with connect by prior

    一.基本语法 connect by递归查询基本语法是: select 1 from 表格 start with ... connect by prior id = pId start with:表示以 ...

  4. Oracle递归查询,Oracle START WITH……CONNECT BY查询

    Oracle递归查询,Oracle START WITH……CONNECT BY查询,Oracle树查询 ================================ ©Copyright 蕃薯耀 ...

  5. sqlserver实现树形结构递归查询(无限极分类)

    SQL Server 2005开始,我们可以直接通过CTE来支持递归查询,CTE即公用表表达式 百度百科 公用表表达式(CTE),是一个在查询中定义的临时命名结果集将在from子句中使用它.每个CTE ...

  6. Oracle递归查询与常用分析函数

    最近学习oracle的一些知识,发现自己sql还是很薄弱,需要继续学习,现在总结一下哈. (1)oracle递归查询  start with ... connect by prior ,至于是否向上查 ...

  7. SqlServer中创建Oracle连接服务器

    转自太祖元年的:http://www.cnblogs.com/jirglt/archive/2012/06/10/2544025.html参考:http://down.51cto.com/data/9 ...

  8. sqlserver cte递归向上统计

    数据字典如下

  9. SqlServer中创建Oracle链接服务器

    SqlServer中创建Oracle链接服务器 第一种:界面操作 (1)展开服务器对象-->链接服务器-->右击“新建链接服务器” (2)输入链接服务器的IP (3)链接成功后 第二种:语 ...

随机推荐

  1. Hibernate如何一个类映射两个表

    一个User类有username,password属性,还有 otherInformation等其他属性,username和password映射到一个表,otherInformation等其他属性映射 ...

  2. MFC弹出模拟对话框

    Windows对话框分为两类:模态对话框和非模态对话框. 模态对话框是这样的对话框,当它弹出后,本应用程序其他窗口将不再接受用户输入,只有该对话框响应用户输入,在对它进行相应操作退出后,其他窗口才能继 ...

  3. Linux中查看进程的多线程pstree, ps -L

    Linux中查看进程的多线程 在SMP系统中,我们的应用程序经常使用多线程的技术,那么在Linux中如何查看某个进程的多个线程呢? 本文介绍3种命令来查看Linux系统中的线程(LWP)的情况:在我的 ...

  4. [转载][HTML] 普通的DIV分层以及版透明效果

    来源忘记哪的了,我稍微做了点修改,想了想还是挂了转载的标签,嗯嗯: <html> <head> <title>EXAMPLE</title> </ ...

  5. [Hibernate] List 映射例子

    List 是 java 集合的一个工具,存储线性的数据,允许重复数据.开发者可以准确控制在 list 那个位置插入数据.本例子演示 Java 的 List 集合和 MySQL 数据库的映射应用. 使用 ...

  6. 《University Calculus》-chape4-导数的应用-极值点的二阶导数检验法

    函数凹凸性检验: 很容易看到,观察类似抛物线这类曲线,能够看到它们有一个向上凹或者向下凹的这样一个过程,而我们将这个过程细化并观察一系列点的导数的变化情况我们给出如下的定义: (1)如果函数图像在区间 ...

  7. Linux 输出重定向>和>>的区别是什么

    > 是定向输出到文件,如果文件不存在,就创建文件:如果文件存在,就将其清空:一般我们备份清理日志文件的时候,就是这种方法:先备份日志,再用`>`,将日志文件清空(文件大小变成0字节): & ...

  8. Delphi图像处理 -- RGB与HSL转换

    阅读提示:     <Delphi图像处理>系列以效率为侧重点,一般代码为PASCAL,核心代码采用BASM.     <C++图像处理>系列以代码清晰,可读性为主,全部使用C ...

  9. listview 遇到问题java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0

    开发的时候 遇到 java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0 这个异常有时候会有,有时候正常 不太好捕捉 猜测 已经 ...

  10. Android自定义Toast宽度无法设置问题解决

    在项目中想要实现一个头部的toast提示效果,类似下图  再实现的过程中发现,如果直接通过修改Toast的View布局的父控件宽度是无法实现效果的,后来是通过直接用代码指定父控件内部的textview ...