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