SQL Server中的公共表表达式(Common Table Expression,CTE)提供了一种便利的方式使得我们进行递归查询。所谓递归查询方便对某个表进行不断的递归从而更加容易的获得带有层级结构的数据。典型的例子如MSDN(https://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx)中提到的获取员工关系层级的结构,如图1所示。

图1.获取员工层级结构

图1所示的例子是一个简单的通过递归获取员工层级的例子,主要理念是通过一个自连接的表(员工表,连接列为员工ID与其上司ID,没有上司的人为公司最大的CEO),不断递归,从而在每次递归时将员工层级+1,最终递归完成后最低级别的员工可以排出其在公司的层级,也就是如图1中所示的3。

图1的例子应用场景比较广泛,网上也有很多文章提到过这种方式,但当我们需要另一种递归方式时,上面的例子就无能为力了。假设我们有这样一个需求,比如现在流程的微商传销的提成方式,假设员工分为3级,分别为一级代理、二级代理、最终销售。那么算业绩的时候可能是重复提成,比如一级代理提二级代理销售额的3%,一级代理提最终销售的1%。二级代理提最终销售的2%等等。那么我们需要从数据库中提取出所有代理的所有利润就不是一件容易的事。一个简单的示意图如图2所示:

图2.多层提成的模型

而此时每一级代理自身又可以直接进行销售,所以代理的销售额并不简单等于其下级代理销售额的和,因此我们最简单的办法就是列出每个代理所有下属的代理,并将其销售额按照业务规则相乘即可。

因此我们需要一个查询将每个代理以及其下属层级全部列出来。由于实际需求可能都是按照省份划分代理,比如广州省是一级,广州市是二级,下属天河区是三级。下面是我们测试数据用的表:

create table #tb(id varchar(3) , pid varchar(3) , name varchar(10))
insert into #tb values('1' , null  , '广东省')
insert into #tb values('2' , '1' , '广州市')
insert into #tb values('3' , '1' , '深圳市')
insert into #tb values('4' , '2' , '天河区')
insert into #tb values('5' , '3' , '罗湖区')
insert into #tb values('6' , '3' , '福田区')
insert into #tb values('7' , '3' , '宝安区')
insert into #tb values('8' , '7' , '西乡镇')
insert into #tb values('9' , '7' , '龙华镇')

代码清单1.测试数据

而我们希望获得的数据类似:

图3.希望获得的数据

在此,我们采用的策略不是与MSDN中的例子不同,而是自下而上递归。代码如代码清单2所示:

WITH    cte ( id, pid, NAME )
          AS ( SELECT   id ,
                        pid ,
                        name 
               FROM     #tb a
               WHERE    a.pid IS NOT NULL
               UNION ALL
               SELECT   b.id ,
                        a.pid ,
                        b.NAME
                    
               FROM     #tb a
                        INNER JOIN cte b ON a.id = b.pid
            WHERE a.pid IS NOT NULL
                        
             )
    SELECT  pid AS id,id AS SID,NAME
    FROM    cte a 
    UNION 
    SELECT id,id,name FROM #tb
    ORDER BY id,sid

代码清单2.从下而上的递归
代码清单2展示了方案,与MSDN自顶向下的例子不同,我们这里采用了自下而上的递归,递归的终止条件是WHERE    a.pid IS NOT NULL,而不是a.pid IS  NULL,该条件使得先从底层开始递归,然后通过a.id = b.pid而不是a.pid=b.id使得查找的过程变为由子节点找父节点,从而实现了上述需求。

SQL Server中CTE的另一种递归方式-从底层向上递归相关推荐

  1. [SQL Server] TSQL实现SQL Server中CTE 递归查询

    参考博客:https://www.cnblogs.com/ljhdo/p/4580347.html 简介 递归查询主要应用于层级结构表的查询: 叶节点-> 根节点的查询 根节点-> 叶节点 ...

  2. 深入浅出SQL Server中的死锁

    简介 死锁的本质是一种僵持状态,是多个主体对于资源的争用而导致的.理解死锁首先需要对死锁所涉及的相关观念有一个理解. 一些基础知识 要理解SQL Server中的死锁,更好的方式是通过类比从更大的面理 ...

  3. 理解SQL Server中索引的概念,原理以及其他

    简介 在SQL Server中,索引是一种增强式的存在,这意味着,即使没有索引,SQL Server仍然可以实现应有的功能.但索引可以在大多数情况下大大提升查询性能,在OLAP中尤其明显.要完全理解索 ...

  4. SQL Server中常用全局变量介绍

    在SQL Server中,全局变量是一种特殊类型的变量,服务器将维护这些变量的值.全局变量以@@前缀开头,不必进行声明,它们属于系统定义的函数.下表就是SQL Server中一些常用的全局变量. 全局 ...

  5. T-SQL查询进阶--理解SQL Server中索引的概念,原理以及其他(看了两次了,转了)

    简介 在SQL Server中,索引是一种增强式的存在,这意味着,即使没有索引,SQL Server仍然可以实现应有的功能.但索引可以在大多数情况下大大提升查询性能,在OLAP中尤其明显.要完全理解索 ...

  6. SQL Server中的万圣节问题和建议的解决方案

    描述 (Description) As per Wikipedia, the Halloween problem was first discovered by Don Chamberlin, Pat ...

  7. 理解SQL Server中索引的概念,原理

    理解SQL Server中索引的概念,原理 摘自:http://51even.iteye.com/blog/1490412 简介 在SQL Server中,索引是一种增强式的存在,这意味着,即使没有索 ...

  8. cte公用表表达式_CTE SQL删除; 在SQL Server中删除具有公用表表达式的数据时的注意事项

    cte公用表表达式 In this article, the latest in our series on Common table expressions, we'll review CTE SQ ...

  9. cte公用表表达式_在SQL Server中使用CTE进行插入和更新(公用表表达式)

    cte公用表表达式 In CTEs in SQL Server; Querying Common Table Expressions the first article of this series, ...

最新文章

  1. Windows 10 全新开始屏幕曝光
  2. 【Deep Learning笔记】感知机模型和学习策略
  3. 本地Windows远程桌面连接阿里云Ubuntu 16.04服务器:
  4. js1:对象的学习,构造函数,继承构造函数【使用教材:JavaScript深度剖析第2版】...
  5. Request_请求转发
  6. 你好,弗朗索瓦丝·萨冈
  7. 手机音频通道被占用_关于凯叔讲故事APP的音频导出下载
  8. 吴恩达深度学习 —— 2.4 梯度下降
  9. asp.net使用 csla 序列化错误 有关于wcf的错误.
  10. poj 1422(二分图)
  11. Linux下l2tp客户端xl2tpd安装配置的具体操作
  12. Ubuntu下Supervisor安装、配置和使用
  13. 安卓实现tcp连接(安卓作为客户端,电脑作为服务端)
  14. 不允许有匹配 [xX][mM][lL] 的处理指令目标
  15. 今日头条的排名算法_今日头条的推荐算法原理分析
  16. 使用M0 DesignStart 的样例SoC(example system) - 4 FPGA原型验证
  17. ida “ failed to load pdb info. 不支持此接口” “DIA: No such interface supported”问题
  18. 可视化全埋点系列文章之功能介绍篇
  19. 程序员的我是如何抢票的(Python)
  20. CC00010.hadoop——|HadoopImpala.V10|——|Impala.v10|集群实现|负载均衡.v01|

热门文章

  1. java基础:13.2 集合框架 - LinkedList、Queue
  2. Elasticsearch一些常用操作和一些基础概念
  3. iOS动画系列之四:基础动画之平移篇
  4. 这才是智能家居真正的现状
  5. NOIP2012pj文化之旅[floyd]
  6. Daily Scrum10 11.14
  7. 计划任务中使用NT AUTHORITY\SYSTEM用户和普通管理员用户有什么差别
  8. [Android学习笔记]startActivityForResult和onActivityResult的使用
  9. Q81:“三角形网格”之“PLY文件”
  10. 推荐系统-Task02数据库基本使用