1. 集合包含性檢測
在一個表中,根據集合的包含性判斷查找記錄。數據庫
【例 1】 在員工表中,統計一線城市各部門的平均工資。部分數據以下:ide
ID | NAME | CITY | SALARY |
1 | Rebecca | Tianjin | 7000 |
2 | Ashley | Tianjin | 11000 |
3 | Rachel | Shijiazhuang | 9000 |
4 | Emily | Shenzhen | 7000 |
5 | Ashley | Nanjing | 16000 |
… | … | … | … |
【解題思路】函數
從員工表選出數據時,須要判斷員工的所在城市是否從屬於由北京、上海、廣州、深圳組成的常數集合。當集合的成員數小於 10 個時,能夠使用函數 A.contain() 進行過濾。優化
【SPL 腳本】spa
A | B | |
1 | =connect("db").query("select * from Employee") | /鏈接數據庫並查詢員工表 |
2 | [Beijing, Shanghai, Guangzhou, Shenzhen] | /建立一線城市的常數集合 |
3 | =A1.select(A2.contain(CITY)) | /使用函數 A.contain() 選出所在城市包含在一線城市中的記錄。 |
4 | =A3.groups(DEPT; avg(SALARY):SALARY) | /分組彙總各部門的平均工資 |
A4的執行結果以下:3d
DEPT | SALARY |
Finance | 7833.33 |
HR | 7187.5 |
Marketing | 7977.27 |
… | … |
在一個表中,根據較大集合的包含性判斷來查找記錄。blog
【例 2】 在銷售表中,統計 2014 年大客戶的每個月銷售額。部分數據以下:排序
ID | Customer | SellerId | Date | Amount |
10400 | EASTC | 1 | 2014/01/01 | 3063.0 |
10401 | HANAR | 1 | 2014/01/01 | 3868.6 |
10402 | ERNSH | 8 | 2014/01/02 | 2713.5 |
10403 | ERNSH | 4 | 2014/01/03 | 1005.9 |
10404 | MAGAA | 2 | 2014/01/03 | 1675.0 |
… | … | … | … | … |
【解題思路】it
本題與【例 1】相似,從銷售表選出數據時,須要判斷銷售客戶是否從屬於大客戶的常數集合。當集合的成員較多時(超過 10 個),能夠先對常數集合排序,再使用函數 A.contain() 的 @b 選項,進行二分法查找。table
【SPL 腳本】
A | B | |
1 | =connect("db").query("select * from Sales") | /鏈接數據庫並查詢銷售表 |
2 | =["SAVEA","QUICK","ERNSH","HUN","RATTC","HANAR","FOLKO","QUEEN,MEREP","WHITC","FRANK","KOENE"].sort() | /建立大客戶的常數集合並排序 |
3 | =A1.select(year(Date)==2014 && A2.contain@b(Customer)) | /選出 2014 年的大客戶記錄。當集合 A 有序時,使用函數 A.contain() 的 @b 選項,進行二分法查找。 |
4 | =A3.groups(month(Date):Month; sum(Amount):Amount) | /分組彙總每個月的銷售額 |
A4的執行結果以下:
STATE | SALARY |
California | 7700.0 |
Texas | 7592.59 |
New York | 7677.77 |
Florida | 7145.16 |
Other | 7308.1 |
2. 外鍵映射的包含性檢測
在兩個表中,根據外鍵映射的包含性檢測查找記錄。
【例 3】 查詢各班有多少學生選修了「Matlab」課程。選課表和課程表以下:
【解題思路】
從選課表選出數據時,須要判斷課程的名稱是否等於「Matlab」。能夠先在課程表中篩選出課程名稱是「Matlab」的課程集合,再選出選課表的課程 ID 從屬於這個集合的記錄。
【SPL 腳本】
A | B | |
1 | =connect("db") | /鏈接數據庫 |
2 | =A1.query("select * from Course") | /查詢課程表 |
3 | =A1.query("select * from SelectCourse") | /查詢選課表 |
4 | =A2.select(Name=="Matlab") | /從課程表中選出指定課程 |
5 | =A3.join@i(CourseID, A4:ID) | /使用函數 A.join() 的 @i 選項進行鏈接過濾 |
6 | =A5.groups(Class; count(1):SelectCount) | /分組彙總各班報名的人數 |
A6的執行結果以下:
Class | SelectCount |
Class 1 | 3 |
Class 2 | 5 |
… | … |
3. 非外鍵的包含性檢測
在兩個表中,根據非外鍵的包含性檢測查找記錄。
【例 4】 查詢各班全部某科成績超過 80 分的學生數量。成績表和學生表以下:
【SQL 語句】
從學生表選出數據時,須要判斷學生是否有單科成績超過 80 分的。能夠先在成績表中選出全部大於 80 分的記錄,再按學生 ID 去重,獲得某科成績高於 80 分的學生 ID 的集合。接下來只要選出學生的 ID 從屬於這個集合的記錄。
【SPL 腳本】
A | B | |
1 | =connect("db") | /鏈接數據庫 |
2 | =A1.query("select * from Student") | /查詢學生表 |
3 | =A1.query("select * from Score") | /查詢學生成績表 |
4 | =A3.select(Score>80) | /選出有成績超過 80 分的記錄 |
5 | =A4.id(StudentID) | /使用 id 函數按學生 ID 去重 |
6 | =A2.join@i(ID, A5) | /使用函數 A.join@i() 鏈接過濾 |
7 | =A6.groups(Class; count(1):StudentCount) | /分組彙總每一個班級的學生數量 |
A7的執行結果以下:
Class | StudentCount |
Class 1 | 9 |
Class 2 | 11 |
… | … |
在兩個表中,根據非外鍵的匹配性檢測查找記錄,優化提速。
【例 5】查詢 2014 年各城市有銷售記錄的客戶數量。銷售表和客戶表以下:
【解題思路】
從客戶表選出數據時,須要判斷客戶在 2014 年是否有銷售記錄。能夠先在銷售表中選出 2014 年的記錄,再按客戶 ID 去重,獲得 2014 年有銷售記錄的客戶 ID 的集合。接下來只要選出客戶表的 ID 從屬於這個集合的記錄。
【SPL 腳本】
A | B | |
1 | =connect("db") | /鏈接數據庫 |
2 | =A1.query("select * from Customer") | /查詢客戶表 |
3 | =A1.query("select * from Sales where year(Date)=2014 order by CustomerID") | /查詢 2014 年的銷售記錄,並按客戶 ID 排序 |
4 | =A3.groups@o(ID) | /使用 groups 函數按客戶 ID 去重,有序時使用 @o 選項 |
5 | =A2.join@i(ID, A4:CustomerID) | /使用函數 A.join@i() 鏈接過濾 |
6 | =A5.groups(City; count(1):CustomerCount) | /分組彙總每一個城市的客戶數量 |
A6的執行結果以下:
City | CustomerCount |
Dongying | 6 |
Tangshan | 7 |
… | … |
4. 外鍵映射的不包含性檢測
在兩個表中,根據外鍵映射的不包含性檢測查找記錄。
【例 6】 查詢 2014 年每一個新增客戶的銷售總額。銷售表和客戶表以下:
【解題思路】
從客戶表選出數據時,須要判斷該客戶在 2014 年沒有銷售記錄。能夠先在銷售表中篩選出 2014 年有銷售記錄的集合,再選出客戶表的 ID 不從屬於這個集合的記錄。
【SPL 腳本】
A | B | |
1 | =connect("db") | /鏈接數據庫 |
2 | =A1.query("select * from Sales where year(OrderDate)=2014") | /查詢 2014 年的銷售記錄 |
3 | =A1.query("select * from Customer") | /查詢客戶表 |
4 | =A2.join@d(CustomerID ,A3:ID) | /使用函數 A.join@d() 從銷售表中選出客戶 ID 在客戶表中不存在的記錄 |
5 | =A4.groups(CustomerID; sum(Amount):Amount) | /分組彙總每一個客戶的銷售額 |
A5的執行結果以下:
CustomerID | Amount |
DOS | 11830.1 |
HUN | 57317.39 |
… | … |
《SPL CookBook》中還有更多相關計算示例。