在数据库中,在表与表之间经常会存在关联关系,如下面的州信息表States(其中Population单位为k),以及主要城市信息表Cities:
Cities通过StateId字段和States关联。数据库中的这种存储模式可以使得数据保持一致,易于维护。
在esProc中,可以通过设置序表的伪字段或者计算列,来体现这种表间关系,使得数据的检索和展现简单而结构明晰。
esProc中可以通过T.dsc()函数为序表添加伪字段,或者使用T.derive()函数为序表添加计算列,先通过下面的例子熟悉一下:
A | B | |
1 | =connect("esProc") | |
2 | =A1.query("select ID,Name,League,Team,IP,ER from PlayersPitching") | |
3 | =A2.dup@t() | |
4 | >A2.deriver(round(ER*9/IP,2):ERA) | |
5 | >A3.dsc(round(ER*9/IP,2):ERA) |
A2中,获取投手信息;A3中,复制A2中的数据以便比较。A4在A2的序表中添加计算列ERA(Earned Run Average),ERA可以根据ER(Earned Run)和IP(Innings Pitched)计算获得;A5则在A3的序表中把ERA添加为伪字段。
A2中的序表如下:
A3中的序表如下:
可以看到,A2和A3中的数据是相同的,只有A3中ERA列的颜色不同。这是由于,A3中ERA是伪字段,这一列的数值并不直接存储于A3的记录 中,而是在读取记录时,临时计算。A2中的计算列则与此不同,它在添加时已经存入了各条记录之中。
我们比较一下这两种情况:T.dec()生成的伪字段仅在数据结构中存储运算关系,因此使用内存较小,但是需要在每一次获取记录时计算;T.derive()生成的计算列则在添加时直接完成计算,数据会直接添加到每一条记录中,便于引用。在实际使用中,可以根据需要使用这两个函数。
了解了如何设定序表的外键,再来看一看我们最初遇到的问题。我们通过T.derive()来设定序表的外键,从而实现表间关联:
7 | =A1.query("select * from States") | B |
8 | =A1.query("select * from Cities") | |
9 | >A7.deriver(A8.select(StateId==A7.StateId):Cities) | |
10 | >A8.deriver(A7.select@1(StateId==A8.StateId):State) | >A8.deriver(State.Name:SName) |
A7和A8分别取出States和Cities的数据。在A9中,在States数据中添加Cities字段作为外键,存储每个州中的城市信息记录。A10则在Cities中添加State字段作为外键,存储城市所在州的信息记录。A11则再为Cites添加SName字段,列出所在州名称,以方便后面的查看。
执行后,A7中的数据为:
鼠标所指的数据为城市记录构成的系列,可以双击查看:
A8中的数据如下:
鼠标指向数据为州记录,也可以双击查看:
可以发现,通过添加外键的方式,无论是A7还是A8中的数据,实际上都已经包含了源数据库中States和Cities这两个表的信息,实现了表间关联。
在查询或者展现时,外键字段的使用和普通字段是相同的,但是在使用中需要注意外键字段的数据类型,在A7中,外键Cities的数据是记录的序列;而A8中,外键State的数据是记录。
如下面的例子,在Cities中,选出州名中包含“la”的数据,可以在过滤表达式中,直接调用外键State的Name字段过滤计算:
11 | =A8.select(like(State.Name,"*la*")) |
计算结果如下:
也可以使用外键字段作为排序依据,如,根据本州中主要城市的数量,对州数据降序排序:
12 | =A7.sort(Cities.len():-1) |
排序结果如下:
如果序表伪字段的记录中,仍然包含伪字段,也是可以继续调用的。如,列出所在州恰好有3个主要城市的城市信息:
13 | =A8.select(State.Cities.len()==3) |