溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何實現(xiàn)報表數(shù)據(jù)的動態(tài)層次鉆取(一)

發(fā)布時間:2020-08-10 15:07:03 來源:ITPUB博客 閱讀:130 作者:rqgxy 欄目:編程語言

在報表項目中有時會遇到進行動態(tài)層次鉆取的需求,這種報表的開發(fā)難度一般都較大。而潤乾報表的實現(xiàn)則相對簡便很多。下面就以《各級部門 KPI 報表》為例,講解潤乾報表(需要結合集算器實現(xiàn))實現(xiàn)此類報表的過程。

《各級部門 KPI 報表》初始狀態(tài)如下圖:

如何實現(xiàn)報表數(shù)據(jù)的動態(tài)層次鉆取(一)

當前節(jié)點是根節(jié)點“河北省”,要求報表顯示當前節(jié)點的下一級節(jié)點“地市”,以及匯總的 KPI 數(shù)值。Kpi 又分為普通指標和 VIP 指標兩類,共四項。當點擊“石家莊”進行鉆取的時候,要求顯示石家莊下一級(區(qū)縣)的 KPI 匯總指標,如下圖:

如何實現(xiàn)報表數(shù)據(jù)的動態(tài)層次鉆取(一)

再點擊“中心區(qū)”進行鉆取,要求顯示下一級(營業(yè)部)的 KPI 匯總指標。以此類推,直到顯示到最后一級。如下圖:

如何實現(xiàn)報表數(shù)據(jù)的動態(tài)層次鉆取(一)

前四級固定是“省、地市、區(qū)縣、營業(yè)部”,后邊則是動態(tài)的“架構 4、架構 5、架構 6. . . 架構 13”(根節(jié)點“省”對應“架構 0”)。

這個報表對應的 oracle 數(shù)據(jù)庫表有兩個,Tree(樹形結構維表)和 kpi(指標事實表)。其中 Tree 表的葉子節(jié)點,通過 id 字段與 kpi 表關聯(lián),數(shù)據(jù)示例如下圖:

如何實現(xiàn)報表數(shù)據(jù)的動態(tài)層次鉆取(一)

                           Tree表

Tree表

如何實現(xiàn)報表數(shù)據(jù)的動態(tài)層次鉆?。ㄒ唬?>
</p>
<pre>
                           Kpi表
</pre>
<p>
<code>
Kpi表
</code>
</p>
<p>
這個報表的難點在于 1、動態(tài)的樹形多層數(shù)據(jù)、標題;2、樹形結構與事實表關聯(lián)。
</p>
<p>
具體實現(xiàn)步驟如下:
</p>
<p>
<span>
第一步
</span>
  編寫集算腳本 tree.dfx,完成源數(shù)據(jù)計算。
</p>
<p>
集算腳本如下:
</p>
<div>
<table width=   A 1 =connect(“ora”) 2 =[“省”,“地市”,“區(qū)縣”,“營業(yè)部”]|to(4,13).(“架構”+string(~)) 3 =A1.query(“SELECT id,name FROM tree    START WITH id = ?    CONNECT BY NOCYCLE PRIOR pid = id order by id”,id) 4 =A3.derive(A2.m(#):title) 5 >level=A3.len() 6 >xtitle=A2.m(level+1) 7 =A1.query@x(“with leaf as( SELECT tree.id id,REGEXP_SUBSTR(SYS_CONNECT_BY_PATH(id, ‘;’),‘[^;]+’,1,2)x FROM tree where connect_by_isleaf=1 START WITH ID = ? CONNECT BY NOCYCLE PRIOR id = pid) select nvl(leaf.x,max(leaf.id)) id,’”+xtitle+“’ title,max(tree.name) name, sum(kpi.kpi1) kpi1,sum(kpi.kpi2) kpi2,sum(kpi.vipkpi1) vipkpi1,sum(kpi.vipkpi2) vipkpi2 from leaf left join kpi on leaf.id = kpi.id left join tree on leaf.x=tree.id group by x order by x”,id) 8 return A4,A7

A1:連接預先配置好的 oracle 數(shù)據(jù)庫。

A2:新建一個序列,內(nèi)容是“省、地市、區(qū)縣、營業(yè)部、架構 4、架構 5、架構 6. . . 架構 13”。

A3:使用 oracle 數(shù)據(jù)庫提供的 connect by 語句編寫 sql,從數(shù)據(jù)庫中取出指定 id(節(jié)點編號)的所有父節(jié)點 id、name。id 是外部參數(shù)“當前節(jié)點”,如果傳進來的值是 104020,那么 A3 的計算結果是:

如何實現(xiàn)報表數(shù)據(jù)的動態(tài)層次鉆取(一)

A4:為 A3 增加一個字段 title,按照順序,對應 A2 中的層級。結果是:

如何實現(xiàn)報表數(shù)據(jù)的動態(tài)層次鉆?。ㄒ唬?>
</p>
<p>
A5:計算變量 level,A3 序表的長度,也就是當前節(jié)點“104020”的層級號“4”(“省”為第一級)。
</p>
<p>
A6:計算輸入節(jié)點“104020”的下一級對應的層級名稱“架構 4”,賦值給變量 xtitle。
</p>
<p>
A7:執(zhí)行 sql 并關閉連接。從 tree 表中取出當前節(jié)點“104020”的所有葉子節(jié)點,并用 sys_connect_by_path 進行計算,得到當前節(jié)點的下一級節(jié)點,形成臨時表 leaf。leaf 再與 kpi 表進行關聯(lián)分組匯總。為了能夠得到當前節(jié)點的下一級節(jié)點的 name,leaf 還需要與 tree 關聯(lián)一次。需要注意的是,如果當前節(jié)點號本身就是葉子節(jié)點,結果中的 name 將為空。完整的 sql 如下:
</p>
<p>
with leaf as(
</p>
<p>
SELECT tree.id id,REGEXP_SUBSTR(SYS_CONNECT_BY_PATH(id, ‘;’),‘[^;]+’,1,2) x FROM tree
</p>
<p>
where connect_by_isleaf=1
</p>
<p>
START WITH ID = ?
</p>
<p>
CONNECT BY NOCYCLE PRIOR id = pid
</p>
<p>
)
</p>
<p>
select nvl(leaf.x,max(leaf.id)) id,‘“+xtitle+”’ title,max(tree.name) name, sum(kpi.kpi1) kpi1,sum(kpi.kpi2) kpi2,sum(kpi.vipkpi1) vipkpi1,sum(kpi.vipkpi2) vipkpi2
</p>
<p>
from leaf left join kpi on leaf.id = kpi.id left join tree on leaf.x=tree.id
</p>
<p>
group by leaf.x order by leaf.x
</p>
<p>
計算的結果是:
</p>
<p>
<img src=MySQL,PostgreSQL 及 Greenplum 等)就很難實現(xiàn) A7 中的 SQL。那么有什么辦法可以讓這些數(shù)據(jù)庫也能實現(xiàn)上述復雜的樹形結構計算呢?

在后續(xù)的文章 《如何實現(xiàn)報表數(shù)據(jù)的動態(tài)層次鉆?。ǘ? 中,我們將介紹如何利用潤乾報表內(nèi)置集算引擎的強大計算能力來解決這個問題。

詳情鏈接: http://c.raqsoft.com.cn/article/1554694583352?r=gxy


向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI