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 都可以很好的解决一对一关联关系。
            
        

英文版