管道

阅读(630) 标签: 管道, 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.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中的结果如下: