在開發數據庫應用時,常常在分組後須要對組內數據進行計算,例如:列出近3年每一年都發表過論文的學生名單(按論文發表年分組後列出每一年都出現的學生清單),統計所有參加了歷次培訓的員工(按培訓分組後統計每次都有的員工人數),選出每位客戶的高爾夫成績最高的三天(按客戶分組後按天計算成績的Top3)等等。java
對於SQL來講,完成這類運算通常較爲複雜,須要嵌套多層,每每致使代碼難以理解和維護困難。而SPL很是擅長這類組內計算,而且很容易和JAVA、報表工具集成。下面用一個例子來進行說明。數據庫
表sales存儲着多年的訂單數據,部分數據以下:ide
OrderID | Client | SellerId | OrderDate | Amount |
10808 | OLDWO | 2 | 2015/1/1 | 1660 |
10809 | WELLI | 7 | 2015/1/1 | 140 |
10810 | LAUGB | 2 | 2015/1/1 | 187 |
10811 | LINOD | 8 | 2015/1/2 | 852 |
10812 | REGGC | 5 | 2015/1/2 | 1852 |
10813 | RICAR | 1 | 2015/1/5 | 648 |
10814 | VICTE | 3 | 2015/1/5 | 2070 |
10815 | SAVEA | 2 | 2015/1/5 | 40 |
10816 | GREAL | 4 | 2015/1/6 | 8891 |
要求是請根據該表統計出指定年份(例如2015)中,每月銷售金額均排在前20名的客戶名稱。函數
解決這個問題的思路是,首先選出2015年銷售數據,按月分組統計,而後循環選出每個月銷售前20名的客戶,最後求各組的交集。工具
這樣的計算在SQL很難直接表達,而SPL則能夠很天然地逐步計算,將複雜問題拆分後得出最終結果。blog
SPL代碼:排序
A | |
1 | =db.query("select * from sales") |
2 | =A1.select(year(ORDERDATE)==YEAR) |
3 | =A2.group(month(ORDERDATE)) |
4 | =A3.(~.group(CLIENT)) |
5 | =A4.(~.top(-20;sum(AMOUNT))) |
6 | =A5.(~.new(CLIENT,sum(AMOUNT):MONTH_AMOUNT)) |
7 | =A6.(~.(CLIENT)) |
8 | =A7.isect() |
A1:從數據庫中讀出銷售表;接口
A2:=A1.select(year(ORDERDATE)==YEAR),從銷售數據中取出指定年份的數據。經過網格參數YEAR靈活適應不一樣的查詢需求,此例中YEAR=2015。固然,這裏的過濾也能夠直接經過A1中的SQL來完成。開發
A3:=A2.group(month(ORDERDATE)),使用group函數,將2015年的數據按照月份分組。這裏須要特別說明的是,SPL的數據分組,是真實的分組,會根據須要將數據實際分爲多個組。這和SQL中的狀況不一樣,SQL中的group by命令是直接計算分組的彙總值,並不能保留中間的分組結果。所以也就沒法對分組的數據進一步計算了。分組後,A3中的數據以下:文檔
咱們還能夠繼續經過雙擊來查看詳細數據,例以下面是三月份的數據:
爲了統計每月中,每一個客戶的月銷售總額,須要再按客戶分組。在SPL中,只須要對每月的數據進行循環,分別按客戶分組就能夠了。循環組內成員時,還可使用簡潔的A.(x)來執行,而沒必要再去編寫循環代碼。
A4:=A3.(~.group(CLIENT))
再次分組後,A4中,每月的數據就都是分組的分組了:
其中3月按客戶分組的數據以下:
能夠看到,3月數據中的每一個分組,都是某個客戶的交易數據。
注意,上述代碼中的「~」表示分組中的每一個成員,針對「~」書寫的代碼就是組內運算代碼,好比上面的~.group(CLIENT)。
接下里,繼續經過組內運算求出每個月排名前20的大客戶:
A5:=A4.(~.top(-20;sum(AMOUNT)))
A6:=A5.(~.new(CLIENT,sum(AMOUNT):MONTH_AMOUNT))
在A5中,循環每月的數據,使用top函數計算出了每個月銷售額最大的前20個客戶。在A6中列出了這些客戶的名稱及月銷售額。A6中計算的結果和3月份的統計數據以下:
最後列出分組內的Client字段,並對各分組求交集:
A7:==A6.(~.(CLIENT))
A8:=A7.isect()
在A7中列出每個月銷售額最大的20個客戶名稱。最後在A8中求12個月的客戶名稱交集,獲得咱們須要的結果以下:
從這個問題中能夠看到,SPL能夠輕鬆實現結構化數據的組內計算,解決問題時的思路很是直觀。組內計算時也可以輕鬆地完成再分組、排序等計算,每一步的數據處理更加清晰天然。此外,SPL提供的組成員循環、求交集等運算也使得計算變得更爲簡易,大大減小了代碼量。
對於計算結果,除了導出數據,SPL還能夠直接以被調用的方式向報表工具或java程序提供數據,調用方法和普通數據庫類似,使用它提供的JDBC接口便可向java主程序返回ResultSet形式的計算結果,具體方法可參考相關文檔。【Java如何調用SPL腳本】