管道

阅读(119) 标签: 管道, channel, push, result, attach,

在游标的使用方法中,前面一再强调过游标是单次遍历的。在7.2.3用游标执行计算 中,我们了解了用游标执行计算,生成新的游标的方法。但是,即使是在这样的使用中,游标仍然只能执行一次遍历计算,只有最终生成的游标中的cs.fetch() 函数能够有效取得数据。遍历结束后,计算过程中产生的其它游标均不能再次读取数据。

有时,在一次读取数据的过程中,我们需要同时计算多个数据,此时可以使用管道。管道与游标类似,可以用channel() 函数新建管道,并用cs.push(ch) 函数将管道添加到游标cs,或者用ch2.push(ch) 函数将管道添加到另一个管道ch2中。管道在新建时只会存储所需计算的动作,只有在游标中实际执行fetch动作取数时才会自动执行计算并记录结果。管道可以执行多种计算,支持的函数与游标类似,如ch.select(), ch.new(), ch.derive(), ch.(), ch.news(), ch.run(), ch.switch(), ch.join(), ch.conj(), ch.group()等。在管道中,可以定义各种结果集,如用ch.fetch() 定义返回管道中的所有数据,用ch.id() 定义返回去重计算的结果,用ch.sortx() 定义返回排序后的结果,或者用ch.groupx() ch.groups() 定义返回分组统计的结果等,也可以用ch.joinx() 将管道中的数据与可分段集文件做连接。因此,管道有两大类函数,一类是附加动作,一类是结果集函数,而管道必须要有附加结果集函数之后才能从管道中取到数据。管道定义了结果集后,可以用ch.result() 函数获取管道中计算的结果。如:

 

A

B

C

D

1

=file("Order_Wines.txt")

 

 

 

2

=A1.cursor@t()

 

 

 

3

=channel()

>A3.select(SalesID==1)

>A3.fetch()

>A2.push(A3)

4

=A2.select(month(Date)==8)

 

 

 

5

=channel()

>A4.push(A5)

>A5.select(SalesID==1)

>A5.fetch()

6

=A4.fetch()

=A3.result()

=A5.result()

 

A6中执行fetch时,游标中的数据被读取出来,管道中的计算也随之完成,这样就可以通过定义管道计算,在一次遍历游标数据的过程中,得到多个计算结果。执行后,A6,B6,C6中的结果如下:

A3A5中新建了管道,两个管道中执行的计算是类似的,都是选出SalesID1的记录。但是可以发现B6C6中的结果是不同的,这是由于A3管道添加到了A2的游标中,A2读取所有销售记录;而A5管道添加到了A4的游标中, A4中的游标添加了计算,只读取8月份的销售数据。

另外,考察第3行与第5行的代码可以发现,在执行push后,管道中仍然可以执行有效的计算。但是,如果已经用ch.fetch(), ch.id() 等函数定义了管道返回的结果,就不能在管道中继续执行计算了。

管道计算的原理是把推送给管道的数据按照运算定义的顺序一步步往下推送,直到最后的结果集函数,下一步的运算是在上一步计算结果的基础上执行的,管道最后只保留结果集函数的计算结果。

 

除了用ch.fetch() 获取全部数据,在管道中还可以使用排序、分组汇总等计算,如:

 

A

B

C

D

1

=file("Order_Wines.txt")

 

 

 

2

=A1.cursor@t()

 

 

 

3

=channel()

>A3.select(SalesID==1)

>A2.push(A3)

 

4

=channel()

>A4.sortx(Amount)

>A3.push(A4)

>A3.groups(month(Date); count(~):Count)

5

=A2.skip ()

=A3.result()

=A4.result()

=C5.fetch()

在这里,A4中的管道添加到了A3的管道中,因此A4管道中的计算会在条件SalesID==1筛选过的记录中执行。A3中定义结果集的groups函数要在最后,因此要放到C4中的push后执行。管道函数ch.sortx() ch.groupx() 等定义的结果集,返回的结果会是游标,需要fetch后才能获得结果,如D5中的处理。另外,虽然A5中执行的是游标的skip操作,这同样也会使游标中的数据流过管道,获得统计结果。计算后,B5, D5中的结果如下:

在管道中附加计算时,除了使用集算器提供的如ch.select(), ch.new() 等函数外,还可以用ch.attach(x) 设定的表达式x来附加计算,表达式中,用~表示管道中前面的计算已经处理过的数据。如:

 

 

B

C

1

=file("Order_Wines.txt")

 

 

2

=A1.cursor@t()

 

 

3

=channel()

>A3.select(SalesID==1)

>A2.push(A3)

4

 

>A3.attach(~.(~.array()))

>A3.fetch()

5

=A2.skip ()

=A3.result()

 

B3中,在管道A3中附加计算,筛选SalesID1的销售记录,在B4中,用函数继续附加计算,将每条记录都转换为序列。执行后,B5中的结果如下: