zoukankan      html  css  js  c++  java
  • sql中的递归拼接

    DB2递归实现字符串分组连接操作

    db2中的递归查询使用with来实现,也称为公共表达式,公共表达式在select语句的开始部分采用with子句的形式,在使用公共表达式的查询中可以多次使用它,并且公共表达式还可以通过取别名来连接到他本身,这样的话就可以达到循环的目的。

    递归查询通常有3个部分需要定义:

    一:一个公共表达式形式的虚拟表。

    二:一个初始化表。

    三:一个与虚拟表进行完全内连接的辅助表。

    需要使用UNION all合并上边3个查询,然后用select从递归输出中得到最终的结果。

    大体上如下形式

    with XX(x1,x2,x3) as  -------@0

    (

    select a.s,a.s1 from a  ----@1

    union all  ----@2

    select * from a,xx where a.s=xx.x1 ------@3

    )

    select ... from xx where .... -------@4

    @0:为with体,即虚拟表

    @1:为初始化表,这里需要定义初始化的一些行,也就是你递归的出发点,或者说父行,这部分逻辑只执行一次,它的结果作为虚拟表递归的初始化内容。

    @2:这里必须用UNION all

    @3:这里需要定义递归的条件(辅助表),这里定义递归的逻辑,需要注意的是父行和子行进行连接的时候逻辑一定要清楚父子关系,不然很容易变成死循环的,这里首先将初始化表的结果作为条件进行查询,在把执行的结果添加到虚拟表中,只要这里能查询出来记录,那么就会进行下一步递归循环。

    @4:这里就是对虚拟表的查询语句。

    需求:一张实时表,一个人每到一个地方,就有一条记录存在,存放样例:

    张三 上海

    张三 杭州

    .....

    要求,按人名进行汇总,将他到过的地方拼接,中间用'#'分隔

    数据准备:

    --创建表:

    CREATE TABLE Recursive_Test

    (User_Name VARCHAR(12),

     City VARCHAR(12));

    --数据插入

    INSERT INTO Recursive_Test(User_Name,City)

          values ('张三','杭州'),('张三','郑州'),('李四','杭州'),

                 ('张三','南昌'),('李四','广州'),('王五','北京');

    -----递归实现:

    WITH Recursive_Test_Par(User_Name,City,Rk_Num) as(

    SELECT User_Name,City,ROW_NUMBER() OVER(PARTITION BY User_Name) --分组,生成序列,自我关联之用

    FROM Recursive_Test

    ),

    City_Join(User_Name,City,R_Num) as(

    SELECT User_Name,CAST(City AS VARCHAR(100)),Rk_Num from Recursive_Test_Par WHERE Rk_Num=1

    UNION ALL

    SELECT a1.User_Name,CAST(a1.City||'#'||b1.City AS VARCHAR(100)),a1.R_Num+1

      from City_Join a1,Recursive_Test_Par b1

    WHERE a1.User_Name=b1.User_Name and a1.R_Num=b1.Rk_Num-1

    SELECT a.User_name,a.City FROM City_Join a INNER JOIN

          (SELECT User_Name,max(R_Num) R_Num from City_Join

           GROUP BY User_Name) b

    ON a.User_name=b.User_name and a.R_Num=b.R_Num;

     --结果:

    王五

    北京

    李四

    杭州#广州

    张三

    杭州#郑州#南昌

    实战例子

    表说明

    ID        巡检组ID     INTEGER

    NAME     巡检组名称

    HYPO     父节点ID, ID=-1 为根节点

    TYPE      =0 是叶子节点 值=1是非叶子节点

    ID          HYPO        NAME                                                                                                                                    TYPE       
    ----------- ----------- --------------------------------------------------------------------------------------------------------------------------------------- -----------
              1          -1 cisco                                                                                                                                            -1
              8           1 交换机巡检                                                                                                                                        0
            429           1 思科设备端口巡检                                                                                                                                  0
            469          -1 huawei                                                                                                                                           -1
            470         469 交换机                                                                                                                                            0
            471         469 huawei-1                                                                                                                                         -1
            472         471 huawei-1-1                                                                                                                                       -1
            473         472 路由器                                                                                                                                            0
    

    sql:

    db2 "
        with rpl (ID,HYPO,NAME,TYPE) AS
        (
            SELECT ID,HYPO,NAME,TYPE FROM T_CHECK_GROUP WHERE HYPO =-1
            UNION ALL
            SELECT child.ID,child.HYPO,CAST(parent.NAME||'~'||child.NAME AS VARCHAR(100)) ,child.TYPE from rpl parent,T_CHECK_GROUP child WHERE parent.ID=child.HYPO 
        )
        select ID,NAME from rpl where TYPE =0"

    res:

              8 cisco~交换机巡检                                                                  
            429 cisco~思科设备端口巡检                                                            
            470 huawei~交换机                                                                     
            473 huawei~huawei-1~huawei-1-1~路由器  
    
    nhz94259@163.com
  • 相关阅读:
    读取STL模型 并用opengl显示
    金币阵列问题
    字典序问题的解决方案
    opengl中的旋转与平移
    copy文件夹,通过C++读取系统、用户名以及计算机名的方法
    poj3032
    菲涅尔反射(Fresnel Reflection)
    几个稍大场景的渲染测试
    Ward BRDF实现心得
    离线渲染中的不规则光源(Meshlight)
  • 原文地址:https://www.cnblogs.com/nhz-M/p/10407379.html
Copyright © 2011-2022 走看看