SQL WITH AS实现父子递归查询.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
SQL WITH AS实现父子递归查询

HYPERLINK /holywolf/archive/2008/12/22/1359546.html SQL Server 2005新特性之使用with关键字解决递归父子关系 1. 引言 现实项目中经常遇到需要处理递归父子关系的问题,如果把层次关系分开,放在多个表里通过主外键关系联接,最明显的问题就是扩展起来不方便,对于这种情况,一般我们会创建一个使用自连接的表来存放数据。例如存放会员地区数据表结构可能是这样: 列名 描述 location_id 地区编号 location_name 地区名称 parentlocation_id 上级地区编号 或者某个部分的职员表结构可能如下所示: 列名 描述 employee_id 职员编号 employee_name 职员名称 manager_id 职员的直接上级管理者,和employee_id进行自联接 通过类似表结构,我们就可以通过一个表理论上管理无限级数的父/子关系,但是当我们需要将这些数据读取出来,不论是填充到一个树中,或是使用级联显示出来,需要花费一定的精力。传统的做法,是做一个递归调用,首先连接数据库将顶层数据(也就是parent_xxx为null的记录)读取出来,再对每一条数据进行递归访问填充集合,这种做法需要连接数据库多次,显然不是较好的解决方法,那么我们能不能通过一次数据库访问,将数据全部读取出来,并且为了按照父子关系形成集合,使返回的数据满足某种格式。 2. 分析 理想情况下,如果父/子关系数据时严格按照关系结构添加到数据库中,亦即首先添加某条父记录,接着添加该父记录的子记录,如果子记录还包含子记录的话继续添加,最终数据表中父/子关系按规则排列数据,我们就可以使用某种算法填充集合,但是正如我们所说,这是理想情况,实际情况下数据经常会发生改变,导致数据没有规律可言,如下图所示,这样的话读取数据填充集合就不太容易的。 所以我们要做的就是通过查询使数据库返回的数据满足这种格式,那么我们的思路是首先查找顶层(0层)记录,再查询第1层记录,接下来是第2层、第3层直到第n层。因为层数是不确定的,所以仍然需要使用递归访问。 SQL Server 2005中提供了新的with关键字,用于指定临时命名的结果集,这些结果集称为公用表表达式(CTE)。该表达式源自简单查询,并且在SELECT、INSERT、UPDATE或DELETE 语句的执行范围内定义。该子句也可用在 CREATE VIEW 语句中,作为该语句的 SELECT 定义语句的一部分。公用表表达式可以包括对自身的引用。这种表达式称为递归公用表表达式。 其语法为: [ WITH common_table_expression [ ,...n ] ] common_table_expression::= expression_name[ ( column_name [ ,...n ] ) ] AS ( CTE_query_definition ) 使用with关键子的一个简单示例,以下代码将tb_loc表中数据源样输出: WITH locs(id,name,parent) AS ( SELECT * FROM tb_loc ) SELECT * FROM locs 为了创建良好层次记录结构集,使用with关键字首先读取顶层记录,并且针对每一条顶层记录读取其子记录,直到读取到最底层级记录,最后将所有的记录组合起来,这里用到了UNION ALL关键字,用于将多个查询结果组合到一个结果集中。 接下来就可以使用该关键字创建存储过程返回结果集,并附加每条记录所位于的“层”数,如下图所示: HYPERLINK /img/holywolf/200812/2008122208292588.jpg 最后需要在前台界面将其显示出来,由于记录已经按层次返回,需要做的就是按层次首其输出,首先将第0层数据输出,接下来将遍历第0层数据,将第一层数据添加到合适的父对象中,重复此过程直到填充结果。那么这里的难题就在于如何查找父对象,我们当然可以遍历集合,但是这么做的话如果数据量很大将导致效率低下。既然可以得到当前对象所位于的层的信息,就也是这树倒置的树是一层一层向下填充的,我们可以定义一个临时集合变量,存储当前层上一层的所有父对象,在插入当前层对象时遍历集合变量以插入到合适的位置,同时我们还必须保证在逐层读取数据时临时集合变量中持有的始终时当前层上一层所有的对象,程序流程图如下所示: 根据以上分析,我们就可以编写实现代码了(为了方便,将本文中用到的数据表和创建记录等SQL语句一并给出)。 3. 实现 3.1 打开SQL Server 2005 Management Studio,选择某个数据库输入以下语句创建表结构

文档评论(0)

zsmfjy + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档