結構化數據中的從屬判斷問題

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》中還有更多相關計算示例。

相關文章
相關標籤/搜索