时间键

阅读(1420) 标签: time,

在序表的主键中,除了可以使用普通的主键,还可以使用一种特殊的主键:时间键。时间键中的数据均为时间日期数据类型,在根据主键查询时可做特殊处理。

时间键的基本使用

在银行交易之类的数据表中,同一账户可能会有很多条交易记录,而所有交易记录中都会有交易时间这样的日期时间数据,在查询时往往又需要根据交易时间去处理,这种情况下可以使用时间键

下面构建一个银行交易表,存储在文件transaction.btx中:

 

A

B

C

1

=create(UID, Amount, Time)

2021-01-01

=5.(12000+rand(9)*1000)

2

for 12

=date(2021, A2, 5)

 

3

 

for C1

=datetime(B2, time(9+rand(9), rand(60), rand(60)))

4

 

 

>A1.insert(0, #B3, B3, C3)

5

for rand(200)+100

=B1+rand(365)

=time(8+rand(15), rand(60), rand(60))

6

 

=-(rand(200)+1)*10

=datetime(B5, C5)

7

 

>A1.insert(0, int(rand(5)+1), B6, C6)

 

8

=A1.sort(Time).group(UID)

 

 

9

=create(UID, Time, Change, Amount)

=5.(10000+rand(200)*100)

>B9.run(A9.insert(0, B9.#, datetime(B1), 0, B9.~))

10

for A8

for A10

>B9(#A10)=B9(#A10)+B10.Amount

11

 

 

>A9.insert(0, #A10, B10.Time, B10.Amount, B9(#A10))

12

=A9.sort(Time)

transaction.btx

=file(B12)

13

>C12.export@b(A12)

=C12.import@b()

 

A1中创建存取款记录表,表中包括用户编号UID,交易金额Amount和交易时间TimeC1中随机生成5位员工的每月工资如下:

2~4行中的代码生成每月5日的工资转入记录,其中C3随机生成交易时间,在C4中将存入工资的账号,金额和时间存入A1的序表中,执行后A1中数据如下:

5~7行中的代码生成2021年的消费记录,其中B6随机生成消费金额,C6随机生成交易日期时间,在C4中将每笔消费的账号,金额和时间存入A1的序表中,帐号随机生成,执行后A1中添加了消费的数据,如下:

A8中将A1中的数据按交易时间排序后,按用户分组,准备用来生成具体的银行交易数据:

A9中生成银行交易数据表,并在C9中填入各个用户2021年初的账户余额,如下:

数据表中包含四个字段:用户编号UID,交易时间Time,金额变动Change和余额Amount。在10~11行,根据各个用户当年的存取款记录,生成每笔交易后的交易数据,其中C10通过计算改变B10中记录的每位账户的余额,C11将交易后的记录填入A9的交易记录表中。

A12将这些交易数据安装交易时间排序后,得到所需的银行交易数据表,在A13中将其存入文件transaction.btx中。B13中读取交易数据记录如下:

 

在使用时间键时,需要先用T.keys@t(K1,K2, ..., KT)来定义,添加@t选项时,定义的字段参数中,最后一个为时间键。一个序表只能有一个时间键,其它主键称为基本键。如:

 

A

B

1

=file("transaction.btx")

 

2

=A1.import@b()

>A2.keys@t(UID, Time)

3

=A2.find(3, date(2021,5,1))

=A2.pfind(3, date(2021,5,1))

4

=A2.find(3, datetime(2021,8,5,18,0,0))

=A2.pfind(3, datetime(2021,8,5,18,0,0))

5

=A2.find(3)

=A2.pfind(3)

B2中,设定序表A2中,基本键为UID,时间键为Time,设定后,A2中数据如下:

可以发现,UIDTime字段都添加了主键标记。

A3中,用T.find(k) 函数根据主键查找记录,结果如下:

和基本键不同,在T.find() 函数中用时间键查找时,并不是用“相等”的关系判断的,而是“指定时间前的最后记录”。以A3中的表达式为例,A2.find(3, date(2021,5,1))中,查找的是3号客户在202151日前的最后一笔交易记录。

T.find() 类似,还可以用T.pfind(k) 函数查找记录序号,如B3中得到的是上面这条记录的序号:

除了使用日期数据,也可以使用时间日期数据来执行有关时间键的查询,如A4B4中结果如下:

 

如果序表指定了时间键,但是在使用T.find()或者T.pfind()函数执行主键查询时,未设置时间键的值,此时将把时间键的查询参数设置为当前时间。如A5中查询=A2.find(3)即相当于计算=A2.find(3, now())。由于时间键的序表中存储的数据往往是历史数据,都会发生在现在时刻之前,因此不设定时间键值的查询,相当于查询基本键满足条件的数据中,最新的一条记录。A5B5中的结果如下:

 

 

定义序表的时间键,只能使用T.keys@t(Ki, ..., KT)函数指定,而不能像基本键一样,在用create(C1, C2, …)函数时用#指定。

在表间关联中使用时间键

如果某个序表中有时间键,在表间关联时,也会根据时间键来处理。如使用A.join(C:…, T:K, x:F, …),将序表T中的记录与排列A相关联时,会根据其中的时间键查找记录,如下面的例子:

 

A

B

1

=file("transaction.btx")

=demo.query("select EID, NAME, DEPT from EMPLOYEE where EID < 6")

2

=A1.import@b()

>A2.keys@t(UID, Time)

3

=B1.join(EID, A2, Time, Amount)

 

4

=B1.join(EID:date(2021,5,1), A2, Time, Amount)

=B1.join(EID:date(2021,5,1), A2:UID:Time, Time, Amount)

B1中,从员工表中读取前5名员工信息如下:

A2中读取上一节中生成的银行交易文件transaction.btx,并在B2中指定序表的基本键为UID,时间键为Time

A3中用A.join()函数,将员工信息与银行交易表连接,连接时根据员工编号EID与银行交易表中的记录匹配,从对应记录中获取TimeAmount两个字段,结果如下:

可以发现,由于B1中的员工表并没有日期时间字段,只凭借EID字段执行连接,因此在银行交易表中,会使用当前时刻执行时间键匹配,得到的数据是最后一笔交易的时间和最终账户余额。

A4中执行连接时,指定了时间为202151日,连接后结果如下:

可以看到,此时查询到的结果是指定时刻前的最后一笔交易状态。使用A.join(C:…, T:K, x:F, …)执行连接时,如果序表T未指定K,则会根据它本身的主键处理,也可以指明连接时使用的主键,如B4中的写法,B4中的结果和A4是相同的。

 

除了使用A.join执行连接时可以使用时间键,在使用A.switch执行表间关联时,也可以使用时间键操作,如:

 

A

B

1

=file("transaction.btx")

=demo.query("select EID, NAME, DEPT from EMPLOYEE where EID < 6")

2

=A1.import@b()

>A2.keys@t(UID, Time)

3

=B1.derive(Date)

 

4

2021-1-1

>A3.run(Date=A4+rand(365))

5

>A3.switch(EID:Date, A2:UID:Time)

=A3.new(EID.UID:ID, NAME, Date, EID.Time:Time, EID.Amount:Amount)

6

>B1.switch(EID, A2)

=B1.new(EID.UID:ID, NAME, EID.Time:Time, EID.Amount:Amount)

A3中在前面例子中的员工资料表基础上,增加了Date字段,并在第4行的代码中随机填入日期数据,填写后A3中数据如下:

A5中,根据上表中的EIDDate两个字段,与A2中的基本键和时间键做关联,转换为对应记录,执行后A3中结果如下,其中EID字段已转换为对应的银行交易记录:

为了便于了解,在B5中根据连接后的数据整理生成了结果序表如下:

可以看到,从EID的交易记录中,获取到的都是Date指明日期前最后一笔交易后的账户状况。A5的表达式中,A2的主键也可以不指定,此时会使用序表本身的主键设置执行switch操作,得到的结果是相同的。

B1的员工资料表中,并没有日期时间类数据,如果用它执行switch操作,就只能使用默认的主键关联情况了,如A6中的情况。B6中在这种状况下整理出连接结果如下:

可见,此时将用当前时刻执行时间键检索,得到的是最终的账户状态。