问题介绍
作为 java 程序员,用代码直接实现类似 SQL 中的交并补差的集合运算,总是要编写大量的代码,如果能有一个专门的外部数据工具,通过写简单类似 SQL 的脚本来实现,在 java 中直接调用并可以返回结果集,就再好不过了。Java 版集算器正是解决这一难题的神器,通过 SPL 脚本可以直观自然得写出运算,再使用 java 调用 SPL 脚本,使用起来简单,快捷,高效。另外,虽然 SQL 有集合概念,但对于有序集合运算提供的支持却很有限,经常要采用很费解的思路才可以完成, SPL 基于离散数据集模型,能轻松处理有序集合运算。下面我们就由浅入深,举例说明如何使用。
SPL 实现
和集
示例 1: 求重叠时间段的总天数
MySQL8:
with recursive t(start,end) as (select date'2010-01-07',date'2010-01-9' union all select date'2010-01-15',date'2010-01-16' union all select date'2010-01-07',date'2010-01-12' union all select date'2010-01-08',date'2010-01-11'), t1(d,end) as (select start,end from t union all select d+1,end from t1 where d select count(distinct d) from t1;
说明:此例先将各时间段转成时间段内所有日子对应的日期,然后再求不同日期的个数
集算器 SPL:
A | |
---|---|
1 | =connect("mysql") |
2 | =A1.query@x("select date'2010-01-07'start,date'2010-01-9'end union all select date'2010-01-15',date'2010-01-16'union all select date'2010-01-07',date'2010-01-12'union all select date'2010-01-08',date'2010-01-11'") |
3 | =A2.(periods(start,end)) |
4 | =A3.conj() |
5 | =A4.icount() |
A3: 对 A2 中的每一个时间段构造从 start 到 end 的日期序列
A4: 求 A3 中所有日期序列的和
A5: 求 A4 中不重复日期的个数
保存脚本文件SumSet.dfx (嵌入 Java 会用到)
差集
示例 1: 列出英语人口和法语人口均超过 5% 的国家
MySQL8:
with t1(lang) as (select 'English' union all select 'French') select name from world.country c where not exists(select * from t1 where lang not in (select language from world.countrylanguage where percentage>=5 and countrycode=c.code ) );
说明:此 SQL 只是演示通过双重否定实现差集为空
集算器 SPL:
A | |
---|---|
1 | =connect("mysql") |
2 | =A1.query("select CountryCode,Name,Language,Percentage from world.countrylanguage cl join world.country c on cl.countrycode=c.code where percentage>5") |
3 | =A2.group(CountryCode) |
4 | =A3.select(["English","French"]\~.(Language)==[]) |
5 | =A4.new(~.Name:name) |
A4: 选出 [“English”,”French”] 与本组语言集合的差为空的组,意思就是选出语言集合包含 English 和 French 的组