1.1 集文件

1.1.1 把数据转储到集文件

文本转储

A
1 =file(“Orders.txt”).cursor@t(CustomerID:string, OrderDate:datetime, ProductID:string, Quantity:int, Unit:string, Price:decimal, Amount:decimal, EmployeeID:int, EmployeeName:string, ShipVia:string)
2 =T(“Orders.btx”:A1)

A1 @t 选项表示第一行是列名(缺省表示无列名),参数中指定要读取的列(缺省全读),以及对应列的数据读进来后转成什么数据类型(缺省根据数据内容自动判断数据类型)。本例中的 Orders.txt 中列间分隔符是缺省值 tab,如果用逗号分隔,则用 @c 选项,如 cursor@c(); 其它分隔符也可在 cursor 函数里指定。

数据库转储

A
1 =connect(“sqlserver2012”)
2 =A1.cursor@x(“select * from Orders”)
3 =T(“Orders.btx”:A2)

A2 @x 表示读完数后自动关闭数据库连接

1.1.2 过滤与分组汇总运算

SQL

SELECT *
FROM Orders
WHERE Amount>1000

SPL

A
1 =file(“Orders.btx”).cursor@mb().select(Amount>1000)
2 =A1.fetch()

A2 @m 选项表示并行读数
注意:读文件的时候可以多个线程并行,每个线程处理一段数据,最后归并成一个结果集,写文件的时候并行就没有效果了,如下图所示:

imagepng

这里假定结果集较小,可以全部读入内存中。如果要向前端返回这个结果集

A
2 return A1.fetch()

大结果集可以直接返回成游标,在前端用 JDBC 再逐条取数

A
2 return A1

或者写成文本供下载

A
2 file(“result.txt”).export@t(A1)

SQL

SELECT EmployeeID,sum(Amount) AS Amount
FROM Orders
GROUP BY EmployeeID
ORDER BY EmployeeID

SPL

A
1 =file(“Orders.btx”).cursor@mb(EmployeeID, Amount)
2 =A1.groups(EmployeeID;sum(Amount):Amount)

A1 只读需要的字段,减少创建对象时间,@m 选项表示并行取数
这里只考虑内存可放下的小结果集,大分组结果集要用

A
2 =A1.groupx(EmployeeID;sum(Amount):Amount)

SQL

SELECT sum(Amount) AS Amount, sum(Quantity) AS Quantity,
count(1) AS num
FROM Orders

SPL

A
1 =file(“Orders.btx”).cursor@mb(Amount, Quantity)
2 =A1.groups(;sum(Amount):Amount, sum(Quantity): Quantity, count(1):num)

A2 groups 不写分组字段参数即表示全集聚合,此时返回值是单行序表
使用 total 函数可以返回序列

A
2 =A1.total(sum(Amount), sum(Quantity), count(1))

SQL

SELECT EmployeeID,count(1) num
FROM Orders
WHERE Amount>1000
GROUP BY EmployeeID

SPL

A
1 =file(“Orders.btx”).cursor@mb(EmployeeID,Amount).select(Amount>1000)
2 =A1.groups(EmployeeID;count(1):num)

SQL

SELECT EmployeeID,sum(Amount) AS Amount
FROM Orders
WHERE OrderDate>='2022-01-01'
GROUP BY EmployeeID
HAVING sum(Amount)>250000

SPL

A
1 =file(“Orders.btx”).cursor@mb(EmployeeID,Amount,OrderDate).select(OrderDate>=date(“2022-01-01”,“yyyy-MM-dd”))
2 =A1.groups(EmployeeID;sum(Amount):Amount).select(Amount>250000)