zoukankan      html  css  js  c++  java
  • CTE递归查询

    --导入数据
    create table dbo.dt_user
    (
        UserID int,
        ManagerID int,
        Name Nvarchar(10)
    )
    
    insert into dbo.dt_user
    select 1,-1,N'Boss'
    union all
    select 11,1,N'A1'
    union all
    select 12,1,N'A2'
    union all
    select 13,1,N'A3'
    union all
    select 111,11,N'B1'
    union all
    select 112,11,N'B2'
    union all
    select 121,12,N'C1'
    --CTE的简单例子
    with cte as
    (
    select UserID,ManagerID,name,name as ManagerName
    from dbo.dt_user
    where ManagerID=-1
    
    union ALL
    
    select c.UserID,c.ManagerID,c.Name,p.name as ManagerName
    from cte P
    inner join dbo.dt_user c
        on p.UserID=c.ManagerID
    )
    select UserID,ManagerID,Name,ManagerName
    from cte
    order by UserID

    1.递归查询至少包含两个子查询

    第一个子查询称作定点(Anchor)子查询:定点查询只是一个返回有效表的查询,用于设置递归的初始值;
    第二个子查询称作递归子查询:该子查询调用CTE名称,触发递归查询,实际上是递归子查询调用递归子查询;
    两个子查询使用union all,求并集;

    2.CTE的递归终止条件

    递归查询没有显式的递归终止条件,只有当递归子查询返回空结果集(没有数据行返回)或是超出了递归次数的最大限制时,才停止递归。

    3.递归步骤

    step1:定点子查询设置CTE的初始值,即CTE的初始值Set0;递归调用的子查询过程:递归子查询调用递归子查询;
    step2:递归子查询第一次调用CTE名称,CTE名称是指CTE的初始值Set0,第一次执行递归子查询之后,CTE名称是指结果集Set1;
    step3:递归子查询第二次调用CTE名称,CTE名称是指Set1,第二次执行递归子查询之后,CTE名称是指结果集Set2;
    step4:在第N次执行递归子查询时,CTE名称是指Set(N-1),递归子查询都引用前一个递归子查询的结果集;
    Step5:如果递归子查询返回空数据行,或超出递归次数的最大限制,停止递归;

    --查询所有子节点
    WITH FCTE AS
    (
        SELECT ContentId,FatherContentId,0 as Level FROM ProductSeries_Content AS PSC
        WHERE FatherContentId = 1
        UNION ALL
        SELECT b.ContentId,b.FatherContentId,a.Level+1 as Level FROM FCTE AS a
        INNER JOIN ProductSeries_Content AS b
        ON a.ContentId = b.FatherContentId
    )
    SELECT * FROM FCTE 
    
    --查询所有父节点
    WITH TCTE AS
    (
        SELECT ContentId,FatherContentId FROM ProductSeries_Content AS PSC
        WHERE ContentId = 260
        UNION ALL
        SELECT b.ContentId,b.FatherContentId FROM TCTE AS a
        INNER JOIN ProductSeries_Content AS b
        ON a.FatherContentId = b.ContentId
    )
    SELECT * FROM TCTE 
    
    
    --补充2点
    --The statement terminated. The maximum recursion 100 has been exhausted before statement completion.
    --递归次数超过100次,要设置递归次数限制
    OPTION(MAXRECURSION 0)
    --注意!注意!注意! ContentId的值不能等于FatherContentId,这样数据会无限递归

     

  • 相关阅读:
    Android总结篇系列:Android Service
    Android 6.0 扫描不到 Ble 设备需开启位置权限
    玩转Android之Drawable的使用
    玩转Android之二维码生成与识别
    玩转Android之数据库框架ActiveAndroid的使用
    玩转Android之加速度传感器的使用,模仿微信摇一摇
    玩转Android之在线视频播放控件Vitamio的使用
    Android5.0之TextInputLayout、FloatingActionButton的使用
    Android自定义View之ProgressBar出场记
    Android5.0之Activity的转场动画
  • 原文地址:https://www.cnblogs.com/lgxlsm/p/7488659.html
Copyright © 2011-2022 走看看