集算器實現 Birt 等報表工具中不規則月份統計
????業務報表中,常常需要基于時間段進行分組統計,特別是按月份分組統計。一般情況如果按自然月就簡單了,但有時候也會需要按不規則月份來分組。例如,某企業從 1 月 16 日開始實行某種特殊的價格策略或營銷活動,因此以后都想以每月 16 號為界來統計產品銷售情況。這里所謂不規則月份就是指: 如果起始時間是 2013-01-16,則將 2013-01-16 到 2013-02-15 作為一組,將 2013-02-16 到 2013-03-15 作為一組。更特別的,如果起始時間是 2013-01-31,則可能要求將 2013-01-31 到 2013-02-27 作為一組,而將 2013-02-28 到 2013-03-30 作為一組,也就是“從每月最后一天”開始分組。
????怎么樣?小伙伴們是不是有點傻眼了?對于 Birt 等報表工具,一般都會提供按自然月分組的表達式,但也卻都難以應對這種不規則月份分組的表達式。如果要解決這個問題,往往需要編寫程序實現自定義報表數據集,而在程序中按這種規則進行分組,不但編程工作量不小,更重要的是基本無法通用。
????現在好了,如果在報表工具中引入集算器,解決這個問題就易如反掌了。下面我們就以 Birt 報表工具為例,講解一下實現的過程。對其它報表工具來說,也基本大同小異。
????在本例中,要統計企業從 2013-01-16 日開始到 2013-08-15 結束,每個月的銷售總額。數據表 salesall 中原始數據如下:

最后需要得到如下圖所示的目標表樣:

?
我們直接來看集算器解決這個問題的 SPL 代碼:
| A | B | |
| 1 | =connect("demo") | |
| 2 | =A1.query("select ? OrderID,Amount,OrderDate from salesall where OrderDate>=?? and OrderDate<? order by ? OrderDate",startDate,endDate) | |
| 3 | =interval@m(startDate,endDate) | =startDate|A3.(elapse@m(startDate,~)) |
| 4 | =A2.group(B3.pseg(OrderDate);round(~.sum(Amount),2),B3(#)) | |
| 5 | =A4.new(#:Number,#2:TotalAmount,#3:StartDate) | |
| 6 | >A1.close() | |
| 7 | return A5 | |
A1?? 連接數據庫
A2?? 從數據庫訂單表中查出統計開始日期到結束日期之間的訂單數據,startDate 和 endDate 是日期參數。
A3?? 根據起止時間算出月份間隔,比如 2013-01-16 和 2013-08-15 間隔 7 個月。
B3?? 根據起始時間和日期間隔算出不規則月份的開始日期,并將起始時間插入第 1 位?!皘”表示合并,“~”表示集合中的當前成員,即數字 1 到 7,結合不同的選項,elapse 函數可以正確計算各種不規則月份的情況。
A4?? 按 B3 區間對 A2 分組,統計出不規則月份的銷售額,保留兩位小數,并將 B3 作為最后一列。函數 pseg 可返回參數,也就是訂購日期所在的區間號。~.sum(Amount)中的~表示分組后的當前組。# 表示 A2 當前組號。
A5?? 取出 A4 的組號作為 Number,第 2 列為 TotalAmount,第 3 列為分組的 StartDate,生成新的結果序表。
A6?? 關閉數據庫
A7?? 將 A5 作為數據集返回給報表工具。
?
將集算器 SPL 代碼存為 orders.dfx 文件,然后引入到 Birt 報表中。如何引入請參看乾學院文章《BIRT 調用 SPL 腳本》。
在 BIRT 中設計簡單的 list 表如下:

?
報表調用集算器的方法和調用存儲過程完全一樣,比如在 BIRT 的存儲過程數據集中可以用 call orders(?,?) 來調用。輸入開始日期參數 2013-01-16、結束日期參數 2013-08-15 后,預覽報表就可以看到要求的目標表樣了。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。