tinyscript之序表操作

原创
2017/10/30 10:51
阅读数 173

       经常操作数据的同学们一定对序表这个名词很熟悉,从结构上来说跟数据库的表结构是类似的。tinyscript的序表是非常实用的数据结构,不仅可以处理数据库,也可以处理excel、文本文档等其他存储方式。相对序列而言,序表具有横纵两个维度,更适合表现固定结构的有序数据。

       提到固定有序的数据结构,很多人第一印象就是通过sql查询出来的表数据,的确数据库使用的场景太多了,但是它的缺点也是很明显:

  • 多表关联sql很复杂,不支持集合运算
  • 无法对查询结果二次加工
  • 不支持其他数据源

      而这些tinyscript的序表都能很简单实现,无需用户额外编码。

      比如说实现A/B两表的关联:

ds1 = [[ SELECT * from A ]].toDynamic();
ds2 = [[ SELECT * from B ]].toDynamic();

//测试内联
inner = ds1.join(ds2,"userid=userid");
println(inner);
println("=================================");

//测试左联
left = ds1.leftjoin(ds2,"userid=userid");
println(left);
println("=================================");

//测试右联
right = ds1.rightjoin(ds2,"userid=userid");
println(right);
println("=================================");

//测试全联
full = ds1.fulljoin(ds2,"userid=userid");
println(full);
println("=================================");

    输出结果如下:

userid username password userid jifen dengji 
1 jack jackpwd 1 20 3 
=================================
userid username password userid jifen dengji 
1 jack jackpwd 1 20 3 
2 open openpwd null null null 
=================================
userid username password userid jifen dengji 
1 jack jackpwd 1 20 3 
null null null 3 50 6 
=================================
userid username password userid jifen dengji 
1 jack jackpwd 1 20 3 
2 open openpwd null null null 
null null null 3 50 6 
=================================

 在tinyscript中序表结构是可以二次编辑的,无论是新增列还是修改记录内容,方便用户二次开发,无需把所有逻辑放到sql语句里面完成。

//序表新建UP列,将CL列的值转换double类型,按CODE字段进行分组,分组内部按DT字段进行升序排列
groupds =ds.insertColumn("UP").double("CL").group("CODE").sortGroup("DT ASC"); //链式命令风格
groupds.update("UP",0d); //更新UP列的结果为0 
groupds.update("UP",(CL[0]-CL[-1])/CL[-1]);  //之后的每天统计当天的涨停率。

     通过join命令或者match命令,用户可以将两个序表进行关联操作,无论它们是否隶属相同数据源。tinyscript的序表操作与数据源无关,这就使得用户操作更加方便。

     序表也支持集合操作(差、并、交、异或),假设我们有如下两个序表:

dataSet1 = readTxt("/dataSetExample/data1.txt");
dataSet2 = readTxt("/dataSetExample/data2.txt");
println(dataSet1);
println("================================================================");
println(dataSet2);
println("================================================================");

    我们可以了解这两个序表的结构如下:

name weight value count 
a 2 6 1 
b 2 3 1 
c 6 5 1 
e 4 6 1 
d 5 4 1 
================================================================
name weight value count 
a 2 6 1 
b 1 3 1 
r 6 5 1 
f 5 4 1 
e 4 6 1 
================================================================

执行序表交集运算

result = dataSet1.intersect(dataSet2,()->{ return name+"|"+weight; });
println(result);
println("================================================================");
result = dataSet1.intersect(dataSet2,["name","weight"]);
println(result);
println("================================================================");

结果如下:

name weight value count 
a 2 6 1 
e 4 6 1 
================================================================
name weight value count 
a 2 6 1 
e 4 6 1 
================================================================

执行序表并集运算

result = dataSet1.unite(dataSet2,()->{ return name+"|"+weight; });
println(result);
println("================================================================");
result = dataSet1.unite(dataSet2,["name","weight"]);
println(result);
println("================================================================");

结果如下:

name weight value count 
a 2 6 1 
b 2 3 1 
c 6 5 1 
e 4 6 1 
d 5 4 1 
b 1 3 1 
r 6 5 1 
f 5 4 1 
================================================================
name weight value count 
a 2 6 1 
b 2 3 1 
c 6 5 1 
e 4 6 1 
d 5 4 1 
b 1 3 1 
r 6 5 1 
f 5 4 1 
================================================================

执行差运算

result = dataSet1.subtract(dataSet2,()->{return name+"|"+weight;});
println(result);
println("================================================================");
result = dataSet1.subtract(dataSet2,["name","weight"]);
println(result);
println("================================================================");

结果如下:

name weight value count 
b 2 3 1 
c 6 5 1 
d 5 4 1 
================================================================
name weight value count 
b 2 3 1 
c 6 5 1 
d 5 4 1 
================================================================

当然序表的分组聚合也是支持,tinyscript设计了三种分组方式:字段分组、静态条件分组和动态条件分组

首先访问数据库获取表结构信息:

defaultDB = "mysql";
d = dynamicDataSource[[ select * from test2 ]].toDynamic();
println(d);

test2信息如下:

ID FULLNAME AGE SEX 
1 莫小二 20 2 
2 张大名 30 1 
3 李德宏 78 2 
4 赵方毅 45 1 
5 John 12 1 
6 冯若依曼 45 1 
7 Tom 12 1 
8 赵真 45 2 
9 邱少云 30 1 
10 王三 12 2 

字段分组是最简单的分组方式,可以说通过sql也可以实现,是最基本常用的分组。

//按年龄和性别分组
println(d.group("age","sex").select("id","fullname"));

结果如下:

----------------------------------------
ID FULLNAME 
----------------------------------------
1 莫小二 
----------------------------------------
2 张大名 
9 邱少云 
----------------------------------------
3 李德宏 
----------------------------------------
4 赵方毅 
6 冯若依曼 
----------------------------------------
5 John 
7 Tom 
----------------------------------------
8 赵真 
----------------------------------------
10 王三 
----------------------------------------

可以看出具有相同年龄和性别的记录分成一组,这也和sql操作结果一致。但是tinyscript的采用链式风格,不用一次性输出全部逻辑,可以通过命令组合降低业务的难度。

第二种分组是静态条件分组,用户输入一组布尔表达式做条件,假设有N个条件,最多输出N+1个分组(其中不匹配所有条件的记录自己成为一组。)

println(d.groupStaged(AGE<=18,AGE>=18 && AGE <60 , AGE>=60));

结果如下:

----------------------------------------
ID FULLNAME AGE SEX 
----------------------------------------
5 John 12 1 
7 Tom 12 1 
10 王三 12 2 
----------------------------------------
1 莫小二 20 2 
2 张大名 30 1 
4 赵方毅 45 1 
6 冯若依曼 45 1 
8 赵真 45 2 
9 邱少云 30 1 
----------------------------------------
3 李德宏 78 2 
----------------------------------------

这种使用场景一般是有业务条件,特别适合if/elseif这种的情况

最后一种情况是动态条件分组,用户输入一个计算表达式,按计算结果的不同进行分组,理论上分组可以是变化的。

println(d.groupDynamic(ID%5));

结果如下:

----------------------------------------
ID FULLNAME AGE SEX 
----------------------------------------
5 John 12 1 
10 王三 12 2 
----------------------------------------
1 莫小二 20 2 
6 冯若依曼 45 1 
----------------------------------------
2 张大名 30 1 
7 Tom 12 1 
----------------------------------------
3 李德宏 78 2 
8 赵真 45 2 
----------------------------------------
4 赵方毅 45 1 
9 邱少云 30 1 
----------------------------------------

无论静态条件分组还是动态条件分组,都是sql语句很难实现的功能,这也是tinyscript的强大所在。

 

小结:

当然序表的功能远不止这一点,碍于篇幅就不能逐一介绍了。tinyscript的序表核心想法是通过链式命令操作,拆分业务逻辑,从而降低整体业务难度;屏蔽底层数据源差异,刚才例子也可以看到我们引用了数据库、文件和csv多种数据源,这样使得用户可以专注于业务逻辑的实现而非底层细节。

更详细的序表功能,用户可以访问tiny的官方论坛获取,相信你一旦用上序表,就会爱上它强大的功能。

tinyscript开源地址:
https://gitee.com/tinyframework/tinyscript.git

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部