开源 SPL 让你在 txt/csv/xls 上跑 SQL
开源集算器 SPL 是一款专业结构化数据计算引擎,拥有丰富的计算类库和完备、不依赖数据库的计算能力。SPL 可以基于多种数据源进行计算,除了原生的 SPL 语法,还可以使用 SQL 查询 txt、csv、xls 等文件,直接把文件当表用,简单方便。
常规查询
基本的过滤、判断空值、条件组合都不在话下:
$select * from d:/Orders.csv
where not Amount>=100 and Client like 'bro' or OrderDate is null
GROUP BY … HAVING 也可以:
$select year(OrderDate),Client ,sum(Amount),count(1) from d:/Orders.csv
group by year(OrderDate),Client
having sum(Amount)<=100
Case…When 都支持:
$select case year(OrderDate) when 2021 then 'this year'
when 2020 then 'last year' else 'previous years' end
from d:/Orders.csv
关联计算也行,左关联、右关联、全关联、内关联都可以:
$select o.OrderId,o.Client,e.Name e.Dept,e.EId from d:/Orders.txt o
left join d:/Employees.txt e on o.SellerId=e.Eid
where 形式的内关联:
$select o.OrderId,o.Client,e.Name e.Dept
from d:/Orders.csv o,d:/Employees.csv e
where o.SellerId=e.Eid
子查询,in 中的子查询,with 子查询都支持:
$with t as (select Client ,sum(amount) s from d:/Orders.csv group by Client)
select t.Client, t.s, ct.Name, ct.address from t
left join ClientTable ct on t.Client=ct.Client
As 别名,union、union all、intersect、minus 都有,还可以使用 into 输出到文件:
$select dept,count(1) c,sum(salary) s into deptResult.xlsx
from employee.txt group by dept having s>100000
特殊情况
SPL 默认可以直接使用 SQL 查询逗号、tab 分隔的 csv、txt,以及 xls 文件,但有时数据形式多种多样,如不是逗号或 tab 分隔的文本,没有标题行的文件、Excel 的指定 sheet 等。这时该如何使用 SQL 查询呢?SPL 也提供了相应方法。
如分隔符是冒号,借助 SPL 扩展函数来处理:
$select * from {file("d:/Orders.txt").import@t (;":")}
where Amount>=100 and Client like 'bro' or OrderDate is null
没有标题行的文件,可以用序号表示列名:
$select * from {file("d:/Orders.txt").import()} where \_4>=100 and \_2 like 'bro' or _5 is null
读取 Excel 指定 sheet:
$select * from {file("D:/Orders.xlsx").xlsimport@t(;"sheet3")}
where Amount>=100 and Client like 'bro' or OrderDate is null
从远程网站下载来的 csv 文件:
$select * from {httpfile("http://127.0.0.1:6868/Orders.csv).import@tc()}
where Amount>=100 and Client like 'bro' or OrderDate is null
Json 文件要先读为字符串再解析:
$select * from {json(file("d:/data.json").read())}
where Amount>=100 and Client like 'bro' or OrderDate is null
更进一步还可以读取 RESTful json:
$select * from {json(httpfile("http://192.168.1.33:6868/api/getData").read())}
where Amount>=100 and Client like 'bro' or OrderDate is null
SPL 提供了 SQL92 标准相当的 SQL 支持,所以尽情用吧。
与应用无缝集成
有了 SPL 的 SQL 支持,在应用中查询计算文件就再也不是问题了。那么怎么在应用中集成 SPL 呢?非常简单,SPL 提供了标准的 JDBC/ODBC/HTTP 接口,与应用分分钟结合在一起。
JDBC 调用:
…
Class.forName("com.esproc.jdbc.InternalDriver");
Connection conn = DriverManager.getConnection("jdbc:esproc:local://");
PrepareStatement st=con.prepareStatement("$select * from D:/Sales.csv where state=?");
st.setObject(1,"California");
st.execute();
ResultSet rs = st.getResultSet();
…
能在应用中用 SQL 查询文件,你说方便不方便?!
英文版