1. 程式人生 > >oracle 層次查詢判斷葉子和根節點

oracle 層次查詢判斷葉子和根節點

               

oracle 9i判斷是葉子或根節點,是比較麻煩的一件事情,SQL演示指令碼如下:

  1. DROPTABLE idb_hierarchical;  
  2. createTABLE idb_hierarchical  
  3. (  
  4. id number,  
  5. parent_id number,  
  6. str varchar2(10)  
  7. );  
  8. insertinto idb_hierarchical values(1,null,'A');  
  9. insertinto idb_hierarchical values(2,1,'B');  
  10. insertinto idb_hierarchical values(3,2,'C');  
  11. insert
    into idb_hierarchical values(4,3,'D');  
  12. insertinto idb_hierarchical values(5,2,'E');  
  13. insertinto idb_hierarchical values(6,2,'F');  
  14. insertinto idb_hierarchical values(7,3,'G');  
  15. insertinto idb_hierarchical values(8,4,'H');  
  16. insertinto idb_hierarchical values(9,4,'I');  
  17. insertinto idb_hierarchical values
    (10,null,'J');  
  18. insertinto idb_hierarchical values(11,10,'K');  
  19. insertinto idb_hierarchical values(12,11,'L');  
  20. insertinto idb_hierarchical values(13,10,'M');  
DROP TABLE idb_hierarchical;create TABLE idb_hierarchical(id number,parent_id number,str varchar2(10));insert into idb_hierarchical values(1,null
,'A');insert into idb_hierarchical values(2,1,'B');insert into idb_hierarchical values(3,2,'C');insert into idb_hierarchical values(4,3,'D');insert into idb_hierarchical values(5,2,'E');insert into idb_hierarchical values(6,2,'F');insert into idb_hierarchical values(7,3,'G');insert into idb_hierarchical values(8,4,'H');insert into idb_hierarchical values(9,4,'I');insert into idb_hierarchical values(10,null,'J');insert into idb_hierarchical values(11,10,'K');insert into idb_hierarchical values(12,11,'L');insert into idb_hierarchical values(13,10,'M');

示例資料清單如下:

  1. SELECT RPAD('+',LEVEL*2+1,'.')||STR STR_LEVEL,ID,PARENT_ID,LEVEL LVL  
  2.   FROM idb_hierarchical  
  3.  START WITH PARENT_ID ISNULL
  4. CONNECTBY PARENT_ID = PRIOR ID;  
SELECT RPAD('+',LEVEL*2+1,'.')||STR STR_LEVEL,ID,PARENT_ID,LEVEL LVL  FROM idb_hierarchical START WITH PARENT_ID IS NULLCONNECT BY PARENT_ID = PRIOR ID;
表1:資料清單
STR_LEVELIDPARENT_IDLVL
+..A11
+….B212
+……C323
+……..D434
+……….H845
+……….I945
+……..G734
+……E523
+……F623
+..J101
+….K11102
+……L12113
+….M13102

在表1中,ID為8、9、 7、5、6、12、13都沒有子節點,因此稱為葉節點。

1.oracle9i 查詢葉節點

只顯示葉子節點SQL

  1. SELECT RPAD('+',LEVEL*2+1,'.')||STR STR_LEVEL,ID,PARENT_ID,LEVEL LVL  
  2.   FROM idb_hierarchical I  
  3.   --在oracle 9i中顯示葉節點,需要判斷是否有子節點即可
  4.   WHERENOT EXISTS(SELECT 1  
  5.   FROM idb_hierarchical B  
  6.   WHERE I.ID=B.PARENT_ID)  
  7.  START WITH PARENT_ID ISNULL
  8. CONNECTBY PARENT_ID = PRIOR ID;  
SELECT RPAD('+',LEVEL*2+1,'.')||STR STR_LEVEL,ID,PARENT_ID,LEVEL LVL  FROM idb_hierarchical I  --在oracle 9i中顯示葉節點,需要判斷是否有子節點即可  WHERE NOT EXISTS(SELECT 1  FROM idb_hierarchical B  WHERE I.ID=B.PARENT_ID) START WITH PARENT_ID IS NULLCONNECT BY PARENT_ID = PRIOR ID;
表2
STR_LEVELIDPARENT_IDLVL
+……….H845
+……….I945
+……..G734
+……E523
+……F623
+……L12113
+….M13102

顯示所有節點,標明該行是否為葉節點SQL

  1. SELECT RPAD('+',LEVEL*2+1,'.')||STR STR_LEVEL,ID,PARENT_ID,LEVEL LVL,  
  2. NVL((SELECT'N'
  3.   FROM idb_hierarchical B  
  4.   WHERE I.ID=B.PARENT_ID  
  5.   AND ROWNUM  < 2),'Y') IS_LEAF  
  6.   FROM idb_hierarchical I  
  7.  START WITH PARENT_ID ISNULL
  8. CONNECTBY PARENT_ID = PRIOR ID;  
SELECT RPAD('+',LEVEL*2+1,'.')||STR STR_LEVEL,ID,PARENT_ID,LEVEL LVL,NVL((SELECT 'N'  FROM idb_hierarchical B  WHERE I.ID=B.PARENT_ID  AND ROWNUM  < 2),'Y') IS_LEAF  FROM idb_hierarchical I START WITH PARENT_ID IS NULLCONNECT BY PARENT_ID = PRIOR ID;
表3
STR_LEVELIDPARENT_IDLVLIS_LEAF
+..A11N
+....B212N
+......C323N
+........D434N
+..........H845Y
+..........I945Y
+........G734Y
+......E523Y
+......F623Y
+..J101N
+....K11102N
+......L12113Y
+....M13102Y

oracle 9i 查詢根節點

  1. SELECT RPAD('+',LEVEL*2+1,'.')||STR STR_LEVEL,ID,PARENT_ID,LEVEL LVL  
  2.   FROM idb_hierarchical I  
  3.  START WITH id =2  
  4. CONNECTBY PARENT_ID = PRIOR ID;  
SELECT RPAD('+',LEVEL*2+1,'.')||STR STR_LEVEL,ID,PARENT_ID,LEVEL LVL  FROM idb_hierarchical I START WITH id =2CONNECT BY PARENT_ID = PRIOR ID;
表4
STR_LEVELIDPARENT_IDLVL
+..B211
+....C322
+......D433
+........H844
+........I944
+......G733
+....E522
+....F622

根節點ID應該為3、5、6,即lvl為1即可

查詢根節點,只顯示根節點SQL

  1. SELECT RPAD('+'LEVEL * 2 + 1, '.') || STR STR_LEVEL,  
  2.        ID,  
  3.        PARENT_ID,  
  4.        LEVEL LVL,  
  5.        (select b.str  
  6.           from idb_hierarchical b  
  7.          wherelevel = 1  
  8.          start with b.id = 2  
  9.         connectbyprior b.id =  b.parent_id  
  10.         ) root_str  
  11.   FROM idb_hierarchical I  
  12.  wherelevel = 1  
  13.  START WITH id = 2  
  14. CONNECTBY PARENT_ID = PRIOR ID;  
SELECT RPAD('+', LEVEL * 2 + 1, '.') || STR STR_LEVEL,       ID,       PARENT_ID,       LEVEL LVL,       (select b.str          from idb_hierarchical b         where level = 1         start with b.id = 2        connect by prior b.id =  b.parent_id        ) root_str  FROM idb_hierarchical I where level = 1 START WITH id = 2CONNECT BY PARENT_ID = PRIOR ID;
表5
STR_LEVELIDPARENT_IDLVLROOT_STR
+..B211B

標明根節點SQL

  1. SELECT RPAD('+'LEVEL * 2 + 1, '.') || STR STR_LEVEL,  
  2.        ID,  
  3.        PARENT_ID,  
  4.        DECODE(LEVEL, 1, 'Y''N') is_root,  
  5.        LEVEL LVL,  
  6.        (select b.str  
  7.           from idb_hierarchical b  
  8.          wherelevel = 1  
  9.          start with b.id = 2  
  10.         connectbyprior b.id = b.parent_id) root_str  
  11.   FROM idb_hierarchical I  
  12.  START WITH id = 2  
  13. CONNECTBY PARENT_ID = PRIOR ID;  
SELECT RPAD('+', LEVEL * 2 + 1, '.') || STR STR_LEVEL,       ID,       PARENT_ID,       DECODE(LEVEL, 1, 'Y', 'N') is_root,       LEVEL LVL,       (select b.str          from idb_hierarchical b         where level = 1         start with b.id = 2        connect by prior b.id = b.parent_id) root_str  FROM idb_hierarchical I START WITH id = 2CONNECT BY PARENT_ID = PRIOR ID;
表6
STR_LEVELIDPARENT_IDIS_ROOTLVLROOT_STR
+..B21Y1B
+....C32N2B
+......D43N3B
+........H84N4B
+........I94N4B
+......G73N3B
+....E52N2B
+....F62N2B

在oracle 10g提供了connect_by_isleaf和connect_by_root

oracle 10g用connect_by_isleaf判斷葉節點

  1. SELECT RPAD('+',LEVEL*2+1,'.')||STR STR_LEVEL,ID,PARENT_ID,LEVEL LVL  
  2.   FROM idb_hierarchical I  
  3. where connect_by_isleaf=1  
  4.  START WITH PARENT_ID ISNULL
  5. CONNECTBY PARENT_ID = PRIOR ID;  
SELECT RPAD('+',LEVEL*2+1,'.')||STR STR_LEVEL,ID,PARENT_ID,LEVEL LVL  FROM idb_hierarchical Iwhere connect_by_isleaf=1 START WITH PARENT_ID IS NULLCONNECT BY PARENT_ID = PRIOR ID;
表7
STR_LEVELIDPARENT_IDLVL
+..........H845
+..........I945
+........G734
+......E523
+......F623
+......L12113
+....M13102
  1. SELECT RPAD('+',LEVEL*2+1,'.')||STR STR_LEVEL,ID,PARENT_ID,LEVEL LVL,  
  2. decode(connect_by_isleaf,1,'Y','N') IS_LEAF  
  3.   FROM idb_hierarchical I  
  4.  START WITH PARENT_ID ISNULL
  5. CONNECTBY PARENT_ID = PRIOR ID;  
SELECT RPAD('+',LEVEL*2+1,'.')||STR STR_LEVEL,ID,PARENT_ID,LEVEL LVL,decode(connect_by_isleaf,1,'Y','N') IS_LEAF  FROM idb_hierarchical I START WITH PARENT_ID IS NULLCONNECT BY PARENT_ID = PRIOR ID;
表8
STR_LEVELIDPARENT_IDLVLIS_LEAF
+..A11N
+....B212N
+......C323N
+........D434N
+..........H845Y
+..........I945Y
+........G734Y
+......E523Y
+......F623Y
+..J101N
+....K11102N
+......L12113Y
+....M13102Y

oracle 10g用connect_by_root判斷根節點

  1. SELECT RPAD('+'LEVEL * 2 + 1, '.') || STR STR_LEVEL,  
  2.        ID,  
  3.        PARENT_ID,  
  4.        LEVEL LVL,  
  5.        connect_by_root STR ROOT_STR  
  6.   FROM idb_hierarchical I  
  7.  START WITH id = 2  
  8. CONNECTBY PARENT_ID = PRIOR ID;  
SELECT RPAD('+', LEVEL * 2 + 1, '.') || STR STR_LEVEL,       ID,       PARENT_ID,       LEVEL LVL,       connect_by_root STR ROOT_STR  FROM idb_hierarchical I START WITH id = 2CONNECT BY PARENT_ID = PRIOR ID;
表9
STR_LEVELIDPARENT_IDLVLROOT_STR
+..B211B
+....C322B
+......D433B
+........H844B
+........I944B
+......G733B
+....E522B
+....F622B
  1. SELECT RPAD('+'LEVEL * 2 + 1, '.') || STR STR_LEVEL,  
  2.        ID,  
  3.        PARENT_ID,  
  4.        DECODE(LEVEL, 1, 'Y''N') is_root,  
  5.        LEVEL LVL,  
  6.        connect_by_root STR ROOT_STR  
  7.   FROM idb_hierarchical I  
  8.  START WITH id = 3  
  9. CONNECTBY PARENT_ID = PRIOR ID;  
SELECT RPAD('+', LEVEL * 2 + 1, '.') || STR STR_LEVEL,       ID,       PARENT_ID,       DECODE(LEVEL, 1, 'Y', 'N') is_root,       LEVEL LVL,       connect_by_root STR ROOT_STR  FROM idb_hierarchical I START WITH id = 3CONNECT BY PARENT_ID = PRIOR ID;
表10
STR_LEVELIDPARENT_IDIS_ROOTLVLROOT_STR
+..C32Y1C
+....D43N2C
+......H84N3C
+......I94N3C
+....G73N2C
  1. SELECT RPAD('+'LEVEL * 2 + 1, '.') || STR STR_LEVEL,  
  2.        ID,  
  3.        PARENT_ID,  
  4.        DECODE(LEVEL, 1, 'Y''N') is_root,  
  5.        LEVEL LVL,  
  6.        connect_by_root STR ROOT_STR  
  7.   FROM idb_hierarchical I  
  8.  START WITH PARENT_ID = 2  
  9. CONNECTBY PARENT_ID = PRIOR ID;  
SELECT RPAD('+', LEVEL * 2 + 1, '.') || STR STR_LEVEL,       ID,       PARENT_ID,       DECODE(LEVEL, 1, 'Y', 'N') is_root,       LEVEL LVL,       connect_by_root STR ROOT_STR  FROM idb_hierarchical I START WITH PARENT_ID = 2CONNECT BY PARENT_ID = PRIOR ID;
表11
STR_LEVELIDPARENT_IDIS_ROOTLVLROOT_STR
+..C32Y1C
+....D43N2C
+......H84N3C
+......I94N3C
+....G73N2C
+..E52Y1E
+..F62Y1F