oracle 層次查詢判斷葉子和根節點
阿新 • • 發佈:2018-12-21
oracle 9i判斷是葉子或根節點,是比較麻煩的一件事情,SQL演示指令碼如下:
- DROPTABLE idb_hierarchical;
- createTABLE idb_hierarchical
- (
- id number,
- parent_id number,
- str varchar2(10)
- );
- insertinto idb_hierarchical values(1,null,'A');
- insertinto idb_hierarchical values(2,1,'B');
- insertinto idb_hierarchical values(3,2,'C');
- insert
- insertinto idb_hierarchical values(5,2,'E');
- insertinto idb_hierarchical values(6,2,'F');
- insertinto idb_hierarchical values(7,3,'G');
- insertinto idb_hierarchical values(8,4,'H');
- insertinto idb_hierarchical values(9,4,'I');
- insertinto idb_hierarchical values
- insertinto idb_hierarchical values(11,10,'K');
- insertinto idb_hierarchical values(12,11,'L');
- 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');
示例資料清單如下:
- SELECT RPAD('+',LEVEL*2+1,'.')||STR STR_LEVEL,ID,PARENT_ID,LEVEL LVL
- FROM idb_hierarchical
- START WITH PARENT_ID ISNULL
- 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;
STR_LEVEL | ID | PARENT_ID | LVL |
---|---|---|---|
+..A | 1 | 1 | |
+….B | 2 | 1 | 2 |
+……C | 3 | 2 | 3 |
+……..D | 4 | 3 | 4 |
+……….H | 8 | 4 | 5 |
+……….I | 9 | 4 | 5 |
+……..G | 7 | 3 | 4 |
+……E | 5 | 2 | 3 |
+……F | 6 | 2 | 3 |
+..J | 10 | 1 | |
+….K | 11 | 10 | 2 |
+……L | 12 | 11 | 3 |
+….M | 13 | 10 | 2 |
在表1中,ID為8、9、 7、5、6、12、13都沒有子節點,因此稱為葉節點。
1.oracle9i 查詢葉節點
只顯示葉子節點SQL
- SELECT RPAD('+',LEVEL*2+1,'.')||STR STR_LEVEL,ID,PARENT_ID,LEVEL LVL
- FROM idb_hierarchical I
- --在oracle 9i中顯示葉節點,需要判斷是否有子節點即可
- WHERENOT EXISTS(SELECT 1
- FROM idb_hierarchical B
- WHERE I.ID=B.PARENT_ID)
- START WITH PARENT_ID ISNULL
- 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;
STR_LEVEL | ID | PARENT_ID | LVL |
+……….H | 8 | 4 | 5 |
+……….I | 9 | 4 | 5 |
+……..G | 7 | 3 | 4 |
+……E | 5 | 2 | 3 |
+……F | 6 | 2 | 3 |
+……L | 12 | 11 | 3 |
+….M | 13 | 10 | 2 |
顯示所有節點,標明該行是否為葉節點SQL
- 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 ISNULL
- 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;
STR_LEVEL | ID | PARENT_ID | LVL | IS_LEAF |
+..A | 1 | 1 | N | |
+....B | 2 | 1 | 2 | N |
+......C | 3 | 2 | 3 | N |
+........D | 4 | 3 | 4 | N |
+..........H | 8 | 4 | 5 | Y |
+..........I | 9 | 4 | 5 | Y |
+........G | 7 | 3 | 4 | Y |
+......E | 5 | 2 | 3 | Y |
+......F | 6 | 2 | 3 | Y |
+..J | 10 | 1 | N | |
+....K | 11 | 10 | 2 | N |
+......L | 12 | 11 | 3 | Y |
+....M | 13 | 10 | 2 | Y |
oracle 9i 查詢根節點
- SELECT RPAD('+',LEVEL*2+1,'.')||STR STR_LEVEL,ID,PARENT_ID,LEVEL LVL
- FROM idb_hierarchical I
- START WITH id =2
- 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;
STR_LEVEL | ID | PARENT_ID | LVL |
+..B | 2 | 1 | 1 |
+....C | 3 | 2 | 2 |
+......D | 4 | 3 | 3 |
+........H | 8 | 4 | 4 |
+........I | 9 | 4 | 4 |
+......G | 7 | 3 | 3 |
+....E | 5 | 2 | 2 |
+....F | 6 | 2 | 2 |
根節點ID應該為3、5、6,即lvl為1即可
查詢根節點,只顯示根節點SQL
- SELECT RPAD('+', LEVEL * 2 + 1, '.') || STR STR_LEVEL,
- ID,
- PARENT_ID,
- LEVEL LVL,
- (select b.str
- from idb_hierarchical b
- wherelevel = 1
- start with b.id = 2
- connectbyprior b.id = b.parent_id
- ) root_str
- FROM idb_hierarchical I
- wherelevel = 1
- START WITH id = 2
- 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;
STR_LEVEL | ID | PARENT_ID | LVL | ROOT_STR |
+..B | 2 | 1 | 1 | B |
標明根節點SQL
- 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
- wherelevel = 1
- start with b.id = 2
- connectbyprior b.id = b.parent_id) root_str
- FROM idb_hierarchical I
- START WITH id = 2
- 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;
STR_LEVEL | ID | PARENT_ID | IS_ROOT | LVL | ROOT_STR |
+..B | 2 | 1 | Y | 1 | B |
+....C | 3 | 2 | N | 2 | B |
+......D | 4 | 3 | N | 3 | B |
+........H | 8 | 4 | N | 4 | B |
+........I | 9 | 4 | N | 4 | B |
+......G | 7 | 3 | N | 3 | B |
+....E | 5 | 2 | N | 2 | B |
+....F | 6 | 2 | N | 2 | B |
在oracle 10g提供了connect_by_isleaf和connect_by_root
oracle 10g用connect_by_isleaf判斷葉節點
- SELECT RPAD('+',LEVEL*2+1,'.')||STR STR_LEVEL,ID,PARENT_ID,LEVEL LVL
- FROM idb_hierarchical I
- where connect_by_isleaf=1
- START WITH PARENT_ID ISNULL
- 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;
STR_LEVEL | ID | PARENT_ID | LVL |
+..........H | 8 | 4 | 5 |
+..........I | 9 | 4 | 5 |
+........G | 7 | 3 | 4 |
+......E | 5 | 2 | 3 |
+......F | 6 | 2 | 3 |
+......L | 12 | 11 | 3 |
+....M | 13 | 10 | 2 |
- 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 ISNULL
- 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;
STR_LEVEL | ID | PARENT_ID | LVL | IS_LEAF |
+..A | 1 | 1 | N | |
+....B | 2 | 1 | 2 | N |
+......C | 3 | 2 | 3 | N |
+........D | 4 | 3 | 4 | N |
+..........H | 8 | 4 | 5 | Y |
+..........I | 9 | 4 | 5 | Y |
+........G | 7 | 3 | 4 | Y |
+......E | 5 | 2 | 3 | Y |
+......F | 6 | 2 | 3 | Y |
+..J | 10 | 1 | N | |
+....K | 11 | 10 | 2 | N |
+......L | 12 | 11 | 3 | Y |
+....M | 13 | 10 | 2 | Y |
oracle 10g用connect_by_root判斷根節點
- 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 = 2
- 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;
STR_LEVEL | ID | PARENT_ID | LVL | ROOT_STR |
---|---|---|---|---|
+..B | 2 | 1 | 1 | B |
+....C | 3 | 2 | 2 | B |
+......D | 4 | 3 | 3 | B |
+........H | 8 | 4 | 4 | B |
+........I | 9 | 4 | 4 | B |
+......G | 7 | 3 | 3 | B |
+....E | 5 | 2 | 2 | B |
+....F | 6 | 2 | 2 | B |
- 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 = 3
- 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;
STR_LEVEL | ID | PARENT_ID | IS_ROOT | LVL | ROOT_STR |
---|---|---|---|---|---|
+..C | 3 | 2 | Y | 1 | C |
+....D | 4 | 3 | N | 2 | C |
+......H | 8 | 4 | N | 3 | C |
+......I | 9 | 4 | N | 3 | C |
+....G | 7 | 3 | N | 2 | C |
- 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 = 2
- 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;
STR_LEVEL | ID | PARENT_ID | IS_ROOT | LVL | ROOT_STR |
---|---|---|---|---|---|
+..C | 3 | 2 | Y | 1 | C |
+....D | 4 | 3 | N | 2 | C |
+......H | 8 | 4 | N | 3 | C |
+......I | 9 | 4 | N | 3 | C |
+....G | 7 | 3 | N | 2 | C |
+..E | 5 | 2 | Y | 1 | E |
+..F | 6 | 2 | Y | 1 | F |