强大的SQL计算利器-SPL_spl 数据库

汇总:T.max(Amount)

分组汇总后过滤: T.groups(year(OrderDate),Client; avg(Amount):amt).select(amt>2000)

关联:join(Orders:o,SellerId ; Employees:e,EId).groups(e.Dept; sum(o.Amount))

交集:T1.id(Client) ^ T2.id(Client)

TopN:T.top(-3;Amount)

分组topN:T.groups(Client;top(3,Amount))

支持动态数据结构,可根据上一步的计算结果推断出新数据结构,并自动生成新序表,新序表可直接进行计算。比如先分组汇总,再过滤,最后排序:

T.groups(SellerId, Client; sum(Amount):amt, count(1):cnt).select(amt>10000 && amt<=30000 && like(Client,“*bro*”)).sort(amt)

使用支持动态数据结构的序表,开发者可以更加关注计算本身,而不是思考如何事先定义结果集。这样的编码风格不仅简短易懂,而且更符合自然思维,开发效率可以显著提升。在多步骤的复杂业务逻辑中,动态数据结构带来的优势更加明显。

强大的结构化数据计算能力

SPL提供了多种方便易用的语法,内置大量功能强大的函数,可以简化复杂的有序运算、集合运算、分布计算、关联计算。很多用SQL和存储过程难以表达的计算,用SPL都可以轻松实现。

函数选项、层次参数等方便的语法,功能相似的函数可以共用一个函数名,只用函数选项区分差别,比SQL更加灵活方便。比如select函数的基本功能是过滤,如果只过滤出符合条件的第1条记录,可使用选项@1:

T.select@1(Amount>1000)

并行过滤,适合数据量较大的情况,使用选项@m:

T.select@m(Amount>1000)

二分法排序,即对有序数据用二分法进行快速过滤,使用@b:

T.select@b(Amount>1000)

有序分组,即对分组字段有序的数据,将相邻且字段值相同的记录分为一组,使用@b:

T.groups@b(Client;sum(Amount))

函数选项还可以组合搭配,比如:

Orders.select@1b(Amount>1000)

结构化运算函数的参数有些很复杂,比如SQL就需要用各种关键字把一条语句的参数分隔成多个组,但这会动用很多关键字,也使语句结构不统一。SPL使用层次参数简化了复杂参数的表达,即通过分号、逗号、冒号自高而低将参数分为三层:

join(Orders:o,SellerId ; Employees:e,EId)

内置大量日期函数和字符串函数,在数量和功能上远远超过其他技术甚至SQL,同样的运算代码量更短。比如:

时间类函数,日期增减:elapse(“2020-02-27”,5) //返回2020-03-03

星期几:day@w(“2020-02-27”) //返回5,即星期4

N个工作日之后的日期:workday(date(“2022-01-01”),25) //返回2022-02-04

字符串类函数,判断是否全为数字:isdigit(“12345”) //返回true

取子串前面的字符串:substr@l(“abCDcdef”,“cd”) //返回abCD

按竖线拆成字符串数组:“aa|bb|cc”.split(“|”) //返回[“aa”,“bb”,“cc”]

SPL还支持年份增减、求年中第几天、求季度、按正则表达式拆分字符串、拆出SQL的where或select部分、拆出单词、按标记拆HTML等功能。

简化复杂的有序运算。涉及跨行的有序运算,通常都有一定的难度,比如比上期和同期比。SPL使用"字段[相对位置]"引用跨行的数据,可显著简化代码,还可以自动处理数组越界等特殊情况,经常比SQL更方便。比如,追加一个计算列rate,计算每条订单的金额增长率:

=T.derive(AMOUNT/AMOUNT[-1]-1: rate)

综合运用位置表达式和有序函数,很多SQL难以实现的有序运算,都可以用SPL轻松解决。比如,根据考勤表,找出连续 4 周每天均出勤达 7 小时的学生:

A
1=connect(“mysql”)
2=A1.query@x(“SELECT SID,ATTDATE,DURATION,null AS W FROM STUTEST WHERE DURATION>=7 ORDER BY SID,ATTDATE”).run(W=pdate@w(ATTDATE))
3=A2.group@o(SID;.groups@o(W;count():CNT).select(CNT==7).group@i(W-W[-1]!=7).max(~.len()):weeks)
4=A3.select(weeks>=4).(SID)

简化复杂的集合运算,SPL序表的集合化更加彻底,配合灵活的语法和强大的集合函数,可大幅简化复杂的集合计算。比如,在各部门找出比本部门平均年龄小的员工:

A
1…//省略序表Employees的生成过程
2=Employees.group(DEPT; (a=.avg(age(BIRTHDAY)),.select(age(BIRTHDAY)<a)):YOUNG)
3=A2.conj(YOUNG)

计算某支股票最长的连续上涨天数:

A
1…//省略序表AAPL的生成过程
2=a=0,AAPL.max(a=if(price>price[-1],a+1,0))

SPL可以方便地实现分步计算,序表的集合化更加彻底,可以用变量方便地表达集合,适合多步骤计算,很多SQL难以表达的集合运算,用SPL都可以轻松实现。比如,找出销售额累计占到一半的前n个大客户,并按销售额从大到小排序:

AB
1//省略取数据的过程
2=A1.sort(amount:-1)/销售额逆序排序,可在SQL中完成
3=A2.cumulate(amount)/计算累计序列
4=A3.m(-1)/2/最后的累计即总额
5=A3.pselect(~>=A4)/超过一半的位置
6=A2(to(A5))/按位置取值

简化复杂的关联计算。序表的专业性体现在多方面,其中之一是支持对象引用的形式表达关联,开发者可以通过点号直观地访问关联表,从而提高开发效率。很多SQL难以表达的关联计算,用SPL都可以轻松实现。比如,根据员工表计算女经理的男员工:

=employees.select(gender:“male”,dept.manager.gender:“female”)

灵活的流程控制能力

SPL提供了灵活易用的分支判断语句、循环语句,配合专业的结构化数据对象,可以方便地实现各类业务逻辑。

分支判断语句

AB
2
3if T.AMOUNT>10000=T.BONUS=T.AMOUNT*0.05
4else if T.AMOUNT>=5000 && T.AMOUNT<10000=T.BONUS=T.AMOUNT*0.03
5else if T.AMOUNT>=2000 && T.AMOUNT<5000=T.BONUS=T.AMOUNT*0.02

循环语句

AB
1=db=connect(“db”)
2=T=db.query@x(“select * from sales where SellerID=? order by OrderDate”,9)
3for T=A3.BONUS=A3.BONUS+A3.AMOUNT*0.01
4=A3.CLIENT=CONCAT(LEFT(A3.CLIENT,4), " co.,ltd.")
5

与Java的循环类似,SPL还可用break关键字跳出(中断)当前循环体,或用next关键字跳过(忽略)本轮循环,不展开说了。

流程控制语句配合序表,可以用统一的语法风格实现业务逻辑,包括数据库读写、事务处理、流程处理、数据计算。比如,根据一定的规则计算奖金:

ABC
1=db=connect@e(“dbName”)/连接数据库,开启事务
2=db.query@1(“select sum(Amount) from sales where sellerID=? and year(OrderDate)=? and month(OrderDate)=?”, p_SellerID,year(now()),month(now()))/查询当月销售额
3=if(A2>=10000 :200, A2<10000 && A2>=2000 :100, 0)/本月累计奖金
4=p_Amount*0.05/本单固定奖金
5=BONUS=A3+A4/总奖金
6=create(ORDERID,CLIENT,SELLERID,AMOUNT,BONUS,ORDERDATE)/创建订单的数据结构
7=A6.record([p_OrderID,p_Client,p_SellerID,p_Amount,BONUS, date(now())])/生成一条订单记录
8>db.update@ik(A7,sales;ORDERID)/尝试写入库表
9=db.error()/入库结果
10if A9==0>A1.commit()/成功,则提交事务
11Else>A1.rollback()/失败,则回滚事务
12>db.close()/关闭数据库连接
13return A9/返回入库结果

优化体系结构

SPL支持JDBC接口,代码可外置于Java,耦合性更低。SPL具有解释执行的特性,支持库外计算和代码移植,支持跨库跨源计算,在SQL后计算中可提供良好的架构性。

SPL提供了易用的JDBC接口,可被Java代码无缝集成。比如,将前面的SPL代码存为脚本文件,再在Java中以存储过程的形式调用文件名:


```java
Class.forName("com.esproc.jdbc.InternalDriver");
Connection connection =DriverManager.getConnection("jdbc:esproc:local://");
Statement statement = connection.createStatement();
ResultSet result = statement.executeQuery("call writeBonus()");

SPL代码外置于Java,通过文件名被调用,既不依赖数据库,也不依赖Java,业务逻辑和前端代码分离,耦合性低。


**解释执行和热切换**。业务逻辑数量多,复杂度高,变化是常态。良好的系统构架,应该有能力应对变化的业务逻辑。ORM的本质是Java代码,需要先编译再执行,一般都要停机才能部署,应对变化的业务逻辑时非常繁琐。SPL是基于Java的解释型语言,无须编译就能执行,脚本修改后立即生效,支持不停机的热切换,适合应对变化的业务逻辑。




![img](https://img-blog.csdnimg.cn/img_convert/62247181e6152f95e72d9588f2de7092.png)
![img](https://img-blog.csdnimg.cn/img_convert/dbed71dbaaf54f4f8267ed5b64be621d.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

6w-1714513919083)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 12
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值