一個樹形聚集SQL問題(二)
看到ITPUB上一個帖子,感覺樓主的需要比較有意思,於是嘗試了一下。問題源自:http://www.itpub.net/thread-1020586-1-1.html
上一篇給出了一個SQL實現,不過由於不是很清楚樓主的含義,加上測試資料過於簡單,沒有將問題完全展現,因此第一篇給出的SQL並不能完全滿足需要。這篇根據新的測試資料來構造求解的SQL。
一個樹形聚集SQL問題(一):http://yangtingkun.itpub.net/post/468/466388
雖然上一篇給出的SQL能得到正確的結果,但是真正的情況比測試中要複雜很多,樹形的分叉並非只可能存在於第一層,而是在任一層都可能包括多個葉節點。
比如插入一條記錄:
SQL> SELECT * FROM T_LEVEL;
LEVELS PARENT CHILD PARENT_QTY CHILD_QTY
---------- ---------- ---------- ---------- ----------
1 A B 1 3
2 B C 2 3
3 C D 5 6
4 D E 1 2
1 A Z 1 3
SQL> INSERT INTO T_LEVEL VALUES (4, 'D', 'F', 1, 3);
已建立 1 行。
SQL> SELECT P,
2 SUBSTR(MAX(D), LENGTH(MAX(D))) C,
3 POWER(10, SUM(LOG(10, Q))) Q
4 FROM
5 (
6 SELECT CONNECT_BY_ROOT(PARENT) P,
7 SYS_CONNECT_BY_PATH(CHILD, '/') D,
8 CHILD_QTY/PARENT_QTY Q
9 FROM T_LEVEL
10 START WITH LEVELS = 1
11 CONNECT BY PRIOR CHILD = PARENT
12 )
13 GROUP BY P, SUBSTR(D, 2, 1);
P C Q
---------- ---------- ----------
A F 32.4
A Z 3
現在得到的結果顯然是不正確的,這裡應該得到3條記錄,A到E、A到F和A到Z。
雖然SQL得到的結果是不正確的,不過解題的思想並沒有變,仍然是透過SUM解決連乘問題,透過構造來獲取聚集的GROUP BY欄位。
為了簡單這個問題,可以將樹形查詢反過來進行,從所有的葉節點出發,彙總資料到根節點,具體實現SQL如下:
SQL> SELECT
2 SUBSTR(MAX(D), INSTR(MAX(D), '/', -1) + 1) C,
3 P,
4 POWER(10, SUM(LOG(10, Q))) Q
5 FROM
6 (
7 SELECT CONNECT_BY_ROOT(CHILD) P,
8 SYS_CONNECT_BY_PATH(PARENT, '/') D,
9 CHILD_QTY/PARENT_QTY Q
10 FROM T_LEVEL
11 START WITH CHILD IN
12 (
13 SELECT CHILD FROM
14 (
15 SELECT CHILD, CONNECT_BY_ISLEAF LEAF FROM T_LEVEL
16 START WITH LEVELS = 1
17 CONNECT BY PRIOR CHILD = PARENT
18 )
19 WHERE LEAF = 1
20 )
21 CONNECT BY PRIOR PARENT = CHILD
22 )
23 GROUP BY P
24 ;
C P Q
------------------------------ ------------------------------ ----------
A Z 3
A E 10.8
A F 16.2
這種方式仍然是10g的方法,因為使用了CONNECT_BY_ISLEAF偽列,而這個偽列是10g的新特性,由來標識當前的記錄是否是葉節點。
如果在9i中,則需要使用別的方法來實現這個功能,實現的SQL如下:
SQL> SELECT
2 SUBSTR(MAX(D), INSTR(MAX(D), '/', -1) + 1) C,
3 SUBSTR(P, 2, INSTR(P, '/', 1, 2) - 2) P,
4 POWER(10, SUM(LOG(10, Q))) Q
5 FROM
6 (
7 SELECT SYS_CONNECT_BY_PATH(CHILD, '/') || '/' P,
8 SYS_CONNECT_BY_PATH(PARENT, '/') D,
9 CHILD_QTY/PARENT_QTY Q
10 FROM T_LEVEL
11 START WITH CHILD IN
12 (
13 SELECT CHILD FROM
14 (
15 SELECT CHILD,
16 CASE WHEN LEAD(LEVELS) OVER(ORDER BY ID) > LEVELS THEN 0 ELSE 1 END LEAF
17 FROM
18 (
19 SELECT ROWNUM ID, LEVELS, PARENT, CHILD
20 FROM T_LEVEL
21 START WITH LEVELS = 1
22 CONNECT BY PRIOR CHILD = PARENT
23 ORDER SIBLINGS BY LEVELS
24 )
25 )
26 WHERE LEAF = 1
27 )
28 CONNECT BY PRIOR PARENT = CHILD
29 )
30 GROUP BY SUBSTR(P, 2, INSTR(P, '/', 1, 2) - 2);
C P Q
------------------------------ ------------------------------ ----------
A Z 3
A E 10.8
A F 16.2
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-401721/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 樹形問題選講
- pl/sql developer的一個小問題SQLDeveloper
- 相同二叉樹和鏡面二叉樹問題二叉樹
- 二叉樹的最小深度問題二叉樹
- SQL Server索引 - 非聚集索引SQLServer索引
- 一類生成樹計數問題。
- 打家劫舍問題合集(普通、有環、二叉樹)二叉樹
- SQL崗位30個面試題,SQL面試問題及答案SQL面試題
- 一個簡單的統計問題(解決方案:Trie樹)
- 10個需要注意的SQL問題SQL
- hudi clustering 資料聚集(二)
- 樹:基本樹形
- [每日一題] 第八題:二叉樹的深度每日一題二叉樹
- [每日一題] 第三題:二叉樹的深度每日一題二叉樹
- 線上問題之慢Sql一定是Sql慢嗎SQL
- 一類子樹問題的總結
- 演算法題(三十五):二叉樹的下一個結點演算法二叉樹
- 50個SQL語句(MySQL版) 問題十四MySql
- 思考一個問題
- 一個小問題
- 刷題系列 - 序列化和反序列化一個二叉樹二叉樹
- 基環樹的一些基本問題
- leetcode 每日一題 617 合併二叉樹LeetCode每日一題二叉樹
- 樹形DP!
- 樹形DP
- 知識全聚集 .Net Core 技術突破 | 如何實現一個模組化方案二
- Leetcode 二叉樹題目集合 (看完這個面試不會做二叉樹題,辣條給你!!!!!)LeetCode二叉樹面試
- 請問一個 authorize的問題
- 樹上染色(樹形dp)
- 008,二叉樹的下一個節點二叉樹
- 發現一個問題
- 記錄一個問題
- 請教一個問題,
- SQL問題診斷SQL
- AcWing 242. 一個簡單的整數問題(樹狀陣列解法)陣列
- leetcode-101-Symmetric Tree-二叉樹對稱問題LeetCode二叉樹
- 【LeetCode二叉樹#17】在二叉搜尋樹中插入或刪除某個值(涉及重構二叉樹、連結串列基礎、以及記憶體洩漏問題)LeetCode二叉樹記憶體
- 樹上最小點覆蓋的一類問題
- LeetCode每日一題: 翻轉二叉樹(No.226)LeetCode每日一題二叉樹