• CTE and CONNECT BY 樹的查詢(轉)


    表    tree
      字段   master
           sub
           sales
      insert into tree values
      ('主1',   '主2',  15); 
      insert into tree values   
      ('主1',   '主3',  20);     
      insert into tree values
      ('主2',   '主4',  5);          
      insert into tree values
      ('主2',   '主5',  10);
      insert into tree values
      ('主3',   '主5',  30);
      insert into tree values
      ('主3',   '主6',  40);
      
      SQL> select * from tree;
      MASTER   SUB       SALES
      ---------- ---------- ----------
      主1    主2        15
      主1    主3        20
      主2    主4         5
      主2    主5        10
      主3    主5        30
      主3    主6        40 
      
      如果用树型结构表示如下:
       '主1'          
         -'主2'       
           --'主4'
           --'主5'
       '主1'          
         -'主3'       
           --'主5'
           --'主6'
      
      SQL> select * from tree                
      start with sub='主2'     --相当于普通sql的where条件
      connect by prior master=sub; --遍历的顺序是sub先于master遍历,也就是说从sub往上遍历一直到master(根节点)
       2 
      MASTER   SUB       SALES
      ---------- ---------- ----------
      主1    主2        15
      
      
      SQL> select * from tree                
      start with master='主2'
      connect by prior master=sub; --sub往上遍历至根节点(参考一下树型图)              
       2  3 
      MASTER   SUB       SALES      
      ---------- ---------- ----------      
      主2    主4         5  --这条是自己本身,也就是第一遍遍历
      主1    主2        15  --这是第2次遍历,我们从树型图可以看到,'主2'往上遍历是'主1'     
      主2    主5        10      
      主1    主2        15      
                            
                             
                            
      好,我们关看上面可能还是不好理解,我们加入一个树结构专用函数sys_connect_by_path,便于理解
      
      SQL> select sys_connect_by_path(MASTER,'/') from tree  --master表示我遍历的起点只找在master列中存在的,如下例只要'主2'为起点,并以/为分割符
      start with master='主2'
      connect by prior master=sub;  --往根节点遍历
       2  3 
      SYS_CONNECT_BY_PATH(MASTER,'/')
      --------------------------------------------------------------------------------
      /主2             --第1遍遍历
      /主2/主1          --第2遍遍历
      /主2             --第2条master='主2'的记录的第1次遍历
      /主2/主1          --第2条master='主2'的记录的第2次遍历
      
      SQL> select sys_connect_by_path(MASTER,'/') from tree --起点为sub='主5'时MASTER=主2,主3
      start with sub='主5'
      connect by prior master=sub;
       2  3 
      SYS_CONNECT_BY_PATH(MASTER,'/')
      --------------------------------------------------------------------------------
      /主2
      /主2/主1
      /主3
      /主3/主1
      
      SQL> select sys_connect_by_path(MASTER,'/'),sub,master from tree  
      start with sub is not null
      connect by prior master=sub; 
       2  3 
      SYS_CONNECT_BY_PATH(MASTER,'/' SUB    MASTER
      ------------------------------ ---------- ----------
      /主1              主2    主1 --找主1到根的路径,这里根是主1他自己
      /主1              主3    主1 
      /主2              主4    主2 
      /主2/主1           主2    主1 --找主2到根的路径,这里根是主1
      /主2              主5    主2
      /主2/主1           主2    主1 
      /主3              主5    主3 
      /主3/主1           主3    主1
      /主3              主6    主3
      /主3/主1           主3    主1  
      select sys_connect_by_path(MASTER,'/'),sub,master from tree                
      start with sub is not null
      connect by prior sub = master;

    SYS_CONNECT_BY_PATH(MASTER,'/' SUB    MASTER
      ------------------------------ ---------- ----------
      /主1              主2    主1
      /主1/主2           主4    主2
      /主1/主2           主5    主2
      /主1              主3    主1
      /主1/主3           主5    主3
      /主1/主3           主6    主3
      /主2              主4    主2
      /主2              主5    主2
      /主3              主5    主3
      /主3              主6    主3


    --------------------
    SELECT *
    FROM
    (
        SELECT b.bomid,
        b.partno, b.version AS partversion, a.componentno, a.version AS componentversion,
        a.alternativegroup, a.itemno, a.flag, a.referencepercentage, a.actualpercentage
        FROM bomdetail a
        INNER JOIN bommaster b ON a.bomid = b.bomid
        WHERE to_date('2008-4-25', 'yyyy-mm-dd hh24:mi:ss') BETWEEN a.validfrom AND a.validto
        AND to_date('2008-4-25', 'yyyy-mm-dd hh24:mi:ss') BETWEEN b.validfrom AND b.validto
    )
    START WITH partno = 'P01' AND partversion = 'AX'
    CONNECT BY PRIOR componentno = partno AND componentversion = partversion
    ORDER BY partno, partversion, componentno, componentversion, itemno;


    --sql server 使用CTE

  • 相关阅读:
    关于网站的性能瓶颈——(阅读笔记)
    Servlet原理解析
    配置Ubuntu Server高速aptget源
    字节对齐
    linux学习笔记—之—linux文件管理
    JavaWeb过滤器Filter
    C语言编程程序的内存布局
    修改Linux下MySQL编码
    C语言中——关于typedef
    linux学习笔记—之—LVM管理
  • 原文地址:https://www.cnblogs.com/wangxiaohuo/p/1176467.html
Copyright © 2020-2023  润新知