結構化數據中的存在判斷問題

1. 外鍵映射的存在性檢測

在兩個表中,根據外鍵映射的存在性查找記錄。數據庫

【例 1】 統計一班男生的平均分。成績表和學生表以下:ide

..

【解題思路】函數

從分數表選出數據時,判斷是否存在班級的名稱是一班且學生性別是男性的記錄,若是存在則選出。spa

【SPL 腳本】3d


A B
1 =connect("db") /鏈接數據庫
2 =A1.query("select * from Score") /查詢學生表
3 =A1.query("select * from   Student") /查詢學生成績表
4 =A3.select(Class=="Class 1"   && Gender=="Male") /選出一班男生
5 =A2.join@i(Class:StudentID, A4:Class:ID) /使用函數 A.join@i() 鏈接過濾
6 =A5.groups(StudentID; avg(Score):Score) /分組彙總每一個學生的平均分

A6的執行結果以下:blog

StudentID Score
1 76
3 74

 

當外鍵表數據量大時,能夠使用遊標的有序歸併來解決。it

【例 2】 查詢 2014 年每個月沒有使用折扣的訂單數量。訂單表和訂單明細表以下:io

..

【解題思路】table

從訂單表選出數據時,判斷是否存在折扣爲 0 的訂單,若是存在則選出。class

【SPL 腳本】


A B
1 =connect("db") /鏈接數據庫
2 =A1.cursor("select * from Order where year(Date)=2014   order by ID") /建立訂單表遊標,選出 2014 年記錄
3 =A1.cursor("select * from Detail order   by ID") /建立訂單明細表遊標
4 =A3.select(Discount==0) /選出沒有使用折扣的記錄
5 =joinx(A2:Order,ID;A4:Detail,ID) /使用函數 joinx 對訂單表和訂單明細表的遊標進行有序歸併
6 =A5.groups(month(Order.Date):Month;   icount(Order.ID):OrderCount) /分組彙總每一個月的訂單數量

A6的執行結果以下:

Month OrderCount
1 16
2 25

 

2. 非等值鏈接的存在性檢測

在一個表中,經過非等值鏈接的存在性檢測查找數據。

【例 3】 查詢同一訂單跨度超過一年的訂單的銷售額。訂單表部分數據以下:

ID NUMBER AMOUNT DELIVERDATE ARRIVALDATE
10814 1 408.0 2014/01/05 2014/04/18
10814 2 204.0 2014/02/21 2014/04/05
10814 3 102.0 2014/03/14 2014/04/06
10814 4 102.0 2014/04/09 2014/04/27
10814 5 102.0 2014/05/04 2014/07/04
10848 1 873.0 2014/01/06 2014/04/21

 

【解題思路】

從訂單表中選出數據時,判斷訂單跨度超過一年的記錄是否存在,若是存在則選出。

【SPL 腳本】


A B
1 =connect("db") /鏈接數據庫
2 =A1.query("select * from Detail") /查詢訂單明細表
3 =A2.group(ID) /按訂單日期分組
4 =A3.select(interval(~.min(DELIVERDATE),   ~.max(ARRIVALDATE)) > 365) /選出同一訂單的時間間隔超過 365 天的記錄
5 =A4.new(ID, ~.sum(AMOUNT):Amount) /建立數據表,統計每一個訂單的銷售額

A5的執行結果以下:

ID Amount
10998 6800.0
11013 4560.0
11032 20615.0

 

3. 外鍵映射的不存在性檢測

在兩個表中,根據外鍵映射的不存在性檢測查找記錄。

【例 4】查詢全部科目均高於 80 分的學生。成績表和學生表以下:

..

【解題思路】

從學生表選出數據時,判斷學生是否存在任意科目低於 80 分的成績,若是不存在則選出。

【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 去重
6 =A2.join@d(ID, A5) /使用函數 A.join@d() 選出不匹配的記錄

A6的執行結果以下:

ID Class Name
2 Class   1 Ashley
16 Class   2 Alexis

 

4. 雙重否認的存在性檢測

經過雙重否認,查詢可以匹配的記錄。

【例 5】 查詢選修了全部課程的學生。選課表、課程表和學生表以下:

..

【解題思路】

從學生表選出數據時,判斷學生是否存在某一科目課程沒有選出的記錄,若是不存在則選出。處理雙重否認的存在性檢測時,咱們也能夠正向思考,只要選出選修科目數量與全部科目數量相同的記錄便可。

【SPL 腳本】


A B
1 =connect("db") /鏈接數據庫
2 =A1.query("select * from   Student") /查詢學生表
3 =A1.query("select * from Course") /查詢課程表
4 =A1.query("select * from   SelectCourse") /查詢選課表
5 =A4.groups(StudentID;   icount(CourseID):CourseCount) /選課表按照學生 ID 分組彙總每一個學生的選課數量
6 =A5.select(CourseCount==A3.len()) /選出選擇了全部課程的學生 ID
7 =A2.join@i(ID, A6:StudentID) /使用函數 A.join@i() 鏈接過濾

A7的執行結果以下:

ID Name Class
4 Emily   Smith Class   1

 

5. 任意條件的存在性檢測

在兩個表中,根據任意條件的存在性檢測查找記錄。

【例 6】 查詢兩科分數差超過 30 分的學生。成績表和學生表以下:

..

【SQL 語句】

從學生表選出數據時,判斷是否存在有任意兩個科目成績相差 30 分的記錄,存在則選出。

【SPL 腳本】


A B
1 =connect("db") /鏈接數據庫
2 =A1.query("select * from   Student") /查詢學生表
3 =A1.query("select * from Score") /查詢成績表
4 =A3.group(StudentID) /成績表按學生 ID 分組
5 =A4.select(~.max(Score)-~.min(Score)>30) /選出最高分和最低分相差超過 30 分的學生
6 =A5.id(StudentID) /按學生 ID 去重
7 =A2.join@i(ID,A6) /使用函數 A.join@i() 鏈接過濾

A7的執行結果以下:

ID Name Class
4 Emily   Smith Class   1
8 Megan Class   1

 

6. 所有條件的存在性檢測

根據一個表中數據,篩選出知足全部條件的記錄。

【例 7】查詢哪些員工的工資比全部銷售部員工都要高。員工表部分數據以下:

ID NAME DEPT SALARY
1 Rebecca R&D 7000
2 Ashley Finance 11000
3 Rachel Sales 9000
4 Emily HR 7000
5 Ashley R&D 16000

 

【SQL 語句】

從員工表選出數據時,判斷員工工資大於全部銷售部員工工資的記錄是否存在,存在則選出。

【SPL 腳本】


A B
1 =connect("db") /鏈接數據庫
2 =A1.query("select * from   Employee") /查詢員工表
3 =A2.select(DEPT:"Sales").max(SALARY) /選出所在城市包含在一線城市中的記錄
4 =A2.select(SALARY>A3) /分組彙總各部門的平均工資

A4的執行結果以下:

ID NAME DEPT SALARY
5 Ashley R&D 16000
20 Alexis Administration 16000
22 Jacob R&D 18000
47 Elizabeth Marketing 17000

 《SPL CookBook》中還有更多相關計算示例。

相關文章
相關標籤/搜索