SPL:一对一连接
连接(JOIN)用于把来自两个或多个表的记录结合起来。本文将探讨对于连接问题,SPL 的解决方案和基本原理。
表之间存在的数据相互依赖关系,就叫做表间关联关系。表间关联关系可以分为以下几种:一对一、多对一、一对多和多对多。我们可以通过表间关联关系,把两个或多个表连接起来,从而实现多表关联查询的目的。
一对一关联,是指一张表的一条记录只能与另外一张表的一条记录进行对应;反之亦然。一对一关联关系常见于两张表都使用相同的主键字段,这样两张表的记录就是一一对应的关系。
例如有学生表和学生联系表,两个表的主键都是学生 ID。第一张表中存储了学生的姓名、性别、生日、系和班级等等基本信息,而学生联系表中存储了学生的联系人和地址等联系方式。每一个学生信息都对应了唯一一条联系方式,每一个联系方式也对应了唯一的学生信息。
【例 1】 根据学生表和学生联系表,查询有联系方式的学生姓名、联系人和住址。部分数据如下:
STUDENT:
ID |
NAME |
DEPARTMENTID |
CLASSID |
GENDER |
BIRTHDAY |
1 |
Rebecca |
1 |
1 |
F |
2010/09/08 |
2 |
Ashley |
1 |
1 |
F |
2010/10/09 |
3 |
Rachel |
1 |
1 |
F |
2011/04/29 |
4 |
Emily |
1 |
1 |
F |
2010/11/24 |
5 |
Ashley |
1 |
1 |
F |
2011/03/03 |
… |
… |
… |
… |
… |
… |
STUDENT_CONTACTS:
ID |
CONTACTS |
ADDRESS |
1 |
Mrs. Moore |
124 Guangming North Road |
2 |
Mrs. Wilson |
116 Baishi Road |
3 |
Mr. Johnson |
No.8, Mingcheng Road, Haidian District |
4 |
Mr. Smith |
12 Fuxing Road |
5 |
Mr. Smith |
462 Shijingshan Road |
… |
… |
… |
根据题意,有的学生可能没有登记联系方式。要查询满足条件的学生姓名和联系方式,我们需要使用内连接,只有学生 ID 在两个表中都存在的记录才会被选出。内连接也叫连接,会从结果表中删除与其他被连接表中没有匹配的所有行。
在 SPL 中称这种一对一关联关系的两个(或多个)表互为同维表。SPL 提供了函数 join() 用于连接,默认为内连接。
SPL脚本如下:
A |
|
1 |
=T("Student.txt") |
2 |
=T("StudentContacts.txt") |
3 |
=join(A1:S,ID;A2:C,ID) |
4 |
=A3.new(S.NAME,C.CONTACTS,C.ADDRESS) |
A1:从文件中导入学生表。
A2:从文件中导入学生联系表。
A3:学生表和学生联系表通过学生 ID 进行内连接。
A4:创建以学生姓名、联系人、联系地址为字段的序表。
SPL同样也支持从数据库中读取数据表,比如数据来源于数据库"db"中 "STUDENT" 表时, A1可以改为:
A |
|
1 |
=connect("db").query("select * from STUDENT") |
【例 2】 根据员工表和经理表,查询所有员工(包括经理)的收入(加上津贴)。部分数据如下:
EMPLOYEE:
ID |
NAME |
BIRTHDAY |
STATE |
DEPT |
SALARY |
1 |
Rebecca |
1974/11/20 |
California |
R&D |
7000 |
2 |
Ashley |
1980/07/19 |
New York |
Finance |
11000 |
3 |
Rachel |
1970/12/17 |
New Mexico |
Sales |
9000 |
4 |
Emily |
1985/03/07 |
Texas |
HR |
7000 |
5 |
Ashley |
1975/05/13 |
Texas |
R&D |
16000 |
… |
… |
… |
… |
… |
… |
MANAGER:
ID |
ALLOWANCE |
18 |
7000 |
2 |
11000 |
4 |
7000 |
6 |
10000 |
7 |
9000 |
… |
… |
经理也是员工,只不过经理表中额外存储了一些信息,例如津贴。要查询所有员工的工资,需要使用左连接,所有的员工不管是否经理都会被选出。左连接也叫左外连接,以左表为基础将两表连接起来。结果会将左表所有的查询信息列出,而右表只列出条件与左表满足的部分。SPL 提供了函数 join() 用于连接,选项 @1 表示左连接。
SPL脚本如下:
A |
|
1 |
=T("Employee.csv") |
2 |
=T("Manager.txt") |
3 |
=join@1(A1:E, ID; A2:M, ID) |
4 |
=A3.new(E.ID, E.NAME, E.SALARY+M.ALLOWANCE:INCOME) |
A1:从文件中导入员工表。
A2:从文件中导入经理表。
A3:员工表和经理表根据员工 ID,以第一个表(员工表)为准进行左连接。
A4:创建以员工 ID、姓名、总收入为字段的序表。
一对一关联关系,在所有关联关系中是最简单的,两个表连接时直接按照主键进行连接即可。无论是 SQL 还是 SPL 都可以很好的解决一对一关联关系。
英文版