• CTE 递归


                  CTE (Common Table Expression)

    他的用法很简单, 形如 with cte_name (cols)

                as ( sql expression) 

    定义如上,使用的时候  可以当做可数据结果集使用  select * from cte_name 

    例如 :

     1 with DBset 
     2 as
     3 (
     4 select OID as 订单号,
     5         case  
     6         when Sale > 0 then Sale
     7         else 0
     8         end as 收入,
     9         case  
    10         when Sale < 0 then ABS(Sale)
    11         else 0 
    12         end as 支出
    13         from [Order]
    14 )
    15 
    16 select * from DBSet where 支出=0

      结果: 

         

      一条cte 表达式 可以在 一段sql表达式重复引用,但是不能在两段 sql 表达式中 重复引用 

     一段sql表达式重复引用: 

    select * from DBSet where 支出=0
    union all 
    select * from DBSet where 收入=0

     结果: 

    不能在两段 sql 表达式中 重复引用:

    select * from DBSet where 支出=0
    union all 
    select * from DBSet where 收入=0
    go
    select * from DBSet

    结果: 

    CTE 递归: 

    说到 CTE递归,首先看 个结果集合  表ColNews :

                              ---------我想让左边表查询显示出右边的需求(也就是显示子节点的层级)------------->

                                    

     

     我们看下 没有 CTE 表达式情况下,怎么实现,  

     1 -- 当没有 CTE,实现方式
     2 create table #item 
     3 (
     4     Id int ,
     5     tLevel int,    
     6 )
     7 
     8 create table #list
     9 (
    10     Id int,
    11     Name nvarchar(50),
    12     ParentId int,
    13     tLevel int
    14 )
    15 
    16 insert into #item 
    17 select Id,0 from ColNews 
    18 where ParentId =0
    19 insert into #list 
    20 select C.Id,C.Name,C.ParentId,#item.tLevel from ColNews as C 
    21 inner join #item 
    22 on C.Id = #item.Id 
    23 --
    24 declare @curID int,@curLevel int
    25 set @curID =1;
    26 set @curLevel = 0;
    27 -- 
    28 while @curID > 0 
    29 begin 
    30 
    31 insert into #item
    32 select C.Id,#item.tLevel+1 from ColNews as C ,#item 
    33 where C.ParentId = #item.Id
    34 
    35 delete from #item 
    36 where #item.tLevel = @curLevel 
    37 
    38 select @curID = COUNT(Id) from #item -- 当 #item 表没有数据,循环中止 
    39 
    40 set @curLevel = @curLevel +1 -- 把当前级别往下推
    41 
    42 insert into #list 
    43 select C.Id,C.Name,C.ParentId,#item.tLevel from ColNews as C 
    44 inner join #item 
    45 on C.Id = #item.Id 
    46 end
    View Code

    可以看到 借助于两个临时表 ,而且代码很多,复杂,不易懂; 现在有了CTE,

    看看 CTE 方式 :

     1 with ColCte (Id,Name,ParentId,tLevel)
     2 as 
     3 (
     4     select *,0 as tLevel from ColNews 
     5     where ColNews.ParentId = 0
     6     union all 
     7     select CN.*,CC.tLevel + 1 as tLevel from ColNews as CN 
     8     inner join ColCte as CC 
     9     on CN.ParentId = CC.Id 
    10 )
    11 
    12 select * from ColCte
    13 Option(MAXRECURSION 3)

    短短不过 10行的代码量,也容易读懂,

  • 相关阅读:
    JS—图片压缩上传(单张)
    vue 使用jssdk分享
    微信JS-SDK选择图片遇到的坑
    手把手教你实现一个微信自动回复机器人
    SSH实现远程控制
    使用Apache服务部署静态网站
    Rhel7安装及网卡、yum、vmtools配置和修改主机名
    基础工具之消息队列、线程池、缓冲区抽象、事件循环和日志实现
    I/O多路复用方案
    Java按字节截取字符串(GBK编码、UTF-8编码实现)
  • 原文地址:https://www.cnblogs.com/rosesBlogs/p/4605299.html
Copyright © 2020-2023  润新知