开发者社区> 润乾软件> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

浅解比 SQL 更好用的 SPL(二)

简介: 从 SQL 到SPL基本查询语法迁移 之多表操作 上一篇我们针对单表的情形了解了如何把数据计算从 SQL 查询迁移到集算器,或者更准确地说,迁移到集算器所使用的SPL集算语言。这个迁移过程,既有相同的概念,也有不同的思路。
+关注继续查看

从 SQL 到SPL基本查询语法迁移 之多表操作

上一篇我们针对单表的情形了解了如何把数据计算从 SQL 查询迁移到集算器,或者更准确地说,迁移到集算器所使用的SPL集算语言。这个迁移过程,既有相同的概念,也有不同的思路。

接下来,我们一起针对多表的情况看一下集算器和SPL语言是如何发挥更大的优势的。

JOIN 连接两个记录
在前面的例子中,我们得到了每个雇员的销售额,如果进一步还想知道每个雇员给出的最小折扣,那就又复杂了些。因为折扣信息在另一张订单明细表里。急性子的朋友可能上来就要 JOIN 两个表,然后再聚合两个测度字段——这样就算错了!正确的做法应该是每个测度字段先按分组聚合出结果,之后再 JOIN。这是因为先 JOIN 的话可能导致结果中出现重复记录。

按照这个思路写出 SQL,并和集算器中的SPL代码进行比较:
SQL
select t1.employeeId, salesAmount, lowestDiscount from (
select employeeId, sum(money) salesAmount from order
where orderDate>=’2012-01-01′ and orderDate<‘2012-02-01’
group by employeeId
having sum(money)>5000) t1
left join (
select employeeId, min(discount) lowestDiscount from order
join orderDetail on order.orderId=orderDetail.orderId
where orderDate>=’2012-01-01′ and orderDate<‘2012-02-01’
group by employeeId) t2
on t1.employeeId=t2.employeeId
1
A5 之前是我们做过的聚合符合条件的按雇员分组的销售额;
A6 查出订单明细表的所有数据;

A7 中的SPL用到了对应 SQL 的多表连接的新函数 join。join 函数把两个表连接起来,这里它的参数的含义是:将 A3 序表起一个别名 order,A6 序表起一个别名 orderDetail,然后用两个表各自的 orderId 作为关联字段,观察 A7 的结果如下:
2

可以看到,join 后形成的序表有 order、orderDetail 两个字段,两个字段的值分别直接指向了两个原始序表的记录,这就是说字段的值可以是复杂数据类型(包括序表、序列类型),也可以嵌套多层结构的数据,这是 SQL 语法里不允许的,也是SPL的特色和优势之一。

下图比较形象地说明了这种结构(长方形表示序表、椭圆形表示记录、三角形表示关联字段):
3

A8 直接用SPL中的 group 函数对这个复杂结构的序表进行分组聚合运算,获得各个雇员曾经给出的最小折扣。

再需要注意的一点是 A3 序表被后面两个不同的动作(A4、A7)都使用了一次,达到了中间结果复用的效果。这种方式对于越是复杂的计算,往往作用越大,可以起到类似“数据模块化”的作用。

在 A9 中通过SPL的 join 函数把 A5(销售额超过 5000)、A8(最小折扣)两个序表连接起来;

最后,A10 使用 new 函数生成新的序表结构,而数据来自 A9 复杂结构记录的不同层次位置。

A10 最终的结果如下:
4

简单回顾一下,对于最后这个比较复杂的 SQL,如果你是个 SQL 高手,可能会看出第二个子查询里的 where 并不是必须的,之所以保留它,是因为有可能会缩小处理数据的范围,从而提升一些性能。这也是 SQL 的另一个特点,一方面需要不喘气的一句话把整个查询表达出来,另一方面还需要同时考虑性能优化因素,甚至即便考虑到了优化方案,也不一定能轻松、自然地描述出来。

在上面的例子中,不难体会出集算器以及SPL对分步过程的重视,每一个步骤的结果都是可以随时观察的,而且前面步骤的结果也可以重复利用,同时执行步骤也可以被程序员自由定制。这些特点最直接的好处是降低了学习和编码的难度,而更本质的是符合人的自然思维,为描述复杂计算奠定了基础。

UNION 等合并两个集合
SQL 中还有一类针对多个集合(表)的运算,就是常说的并、合、交、差(UNION、UNION ALL、INTERSECTION、MINUS),与之对应的,在SPL中表示为 &、|、^、。

集合运算时常需要判断一条记录是否重复,在这个细节上,SQL 和SPL有一点区别。SPL里因为序表、记录,以及字段的值都被看成是一个对象,所以在进行并集运算时,可以比对元素是否为同一个对象,而 SQL 的记录是抽象的,不是一个实体对象,所以只能通过逐个比对两条记录的字段值来判断是否重复。

我们来看一下实际的例子:
5
A3 序表的结果:
6

B3 序表的结果:
7

A3&B3,去掉重复合并到一起,并集运算后得到 A4 序表的结果:
8

A3|B3,保留重复合并到一起,合集运算后得到 B4 序表的结果:
9

A3^B3,取 A3 和 B3 里相同的记录,交集运算后得到 A5 序表的结果:
10

A3B3,A3 里去掉 B3 中存在的记录,差集运算后得到 A5 序表的结果:
12

其它常用语法
最后,再看两个常用的 SQL 函数语法,我们来对比看一下SPL的实现。

CASE WHEN …
SQL 中的 case when … then … else … end,在SPL中用 if 函数,语法是if(条件, 真值, 假值),下面的例子是把 employeeId<5 的分为一组,剩余的分到另一组:
13
COALESCE(exp1,exp2…expn)
SPL中仍然用 if 函数,if(条件, 真值, 假值),下面这个例子把 1000 这个特殊的值赋值给为 null 的 employeeId。
14
集算器(SPL)≠SQL
看完上面这些例子,会给人一个感觉:集算器,或者其中的SPL代码只是 SQL 的替代品,而常用的关系数据库系统(RDBMS)本身已经是存储能力(数据表)+ 计算能力 (SQL) 的综合体了,还要这么一个外来的计算体系干嘛?

针对这个疑问,有两个层面的答案。首先是数据层面,并非所有要计算的数据都在数据库里。当你手边有个文本、excel 或从一个网络服务临时得到一些数据想要计算,或者从大量终端采集上来的数据马上要处理出结果……如果这些都不得不倒腾到数据库里然后再计算,还真是有点太绕了,更何况还可能涉及到数据库的安装部署,或者权限控制等琐碎而现实的问题。

其次是计算层面,对于很多复杂的计算过程,SQL 因为天生缺陷无法做到开发高效、维护高效、执行效高。这也是我们这篇文章最想说明的地方,SQL 的计算主要还是面向查询,而这些对“高效”的追求,面向的是更广泛的数据计算,这正是集算器和SPL语言所要重点改善的。

正因为有了这两个层面的原因,集算器和SPL语言已经可以独立于各种数据存储形式,在“存储”和“应用”之间,作为一个功能完整、形式灵活、部署方便的“数据计算中间件”而存在。这方面的内容,我们会在后面的章节做更多的介绍和探讨。

这里,我们只是先简单看一下集算器和SPL语言如何基于文本、Excel 等数据源进行计算。事实上,前面这些例子中的计算步骤完全不用改写,只需要改变加载数据那一句就可以了。也就是把:

=A1.query(“select * from order”)

改为下列任意方式之一:

=file(“d:/data/order.txt”).import@t()// 从文本文件加载数据表

=file(“d:/data/orderDetail.xls”).importxls@t()// 从 excel 加载数据表

=httpfile(“ http:/ /127.0.0.1/service ”,” param1=value1&param2=value2″) // 从 http server 加载数据表

……

很明显,通过这种简单明了的数据加载方式,可以将各种数据源的数据形成统一的“序表”,从而在一个计算过程里可以轻松混合使用。换句话说,不必为了计算能力而要求必须统一存储方式。同样的,在集算器和SPL的环境中,计算结果的存储,也和加载数据一样方便,也是多样化的,可以由程序员自由选择。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
使用ESC之后的心得体会
云服务器ECS即Elastic Compute Service弹性计算服务,是阿里云提供的最基础的云计算服务,ECS是基于虚拟化技术后的计算单元,使用ECS云服务器可以像用水用电一样便捷,拿来即用。ESC适合批量计算、数据分析、开发web服务、部署数据库等场景,可以给人们带来快捷和便利。
28 0
某酒店App sign、appcode签名解析(二) 脱壳分析
某酒店App sign、appcode签名解析(二) 脱壳分析
49 0
SSM(三)Shiro 使用详解(下)
相比有做过企业级开发的童鞋应该都有做过权限安全之类的功能吧,最先开始我采用的是建用户表,角色表,权限表,之后在拦截器中对每一个请求进行拦截,再到数据库中进行查询看当前用户是否有该权限,这样的设计能满足大多数中小型系统的需求。不过这篇所介绍的Shiro能满足之前的所有需求,并且使用简单,安全性高,而且现在越来越的多企业都在使用Shiro,这应该是一个收入的你的技能库。
26 0
JavaScript的垃圾回收机制,清除无用变量,释放多余内存,展现更好的性能
本篇文章将讲解一下javascript的垃圾回收机制。同时,我们必须先具备作用域链的概念,不懂的小伙伴可以先花3分钟观看一下这篇文章,简单了解一下作用域链的知识——从零开始讲解JavaScript中作用域链的概念及用途
81 0
JavaScript作用域原理(二)——预编译
JavaScript是一种脚本语言, 它的执行过程, 是一种翻译执行的过程。并且JavaScript是有预编译过程的,在执行每一段脚本代码之前, 都会首先处理var关键字和function定义式(函数定义式和函数表达式)。
22 0
mybatis系列之获取mapper.xml配置文件中的sql
hello~各位读者好,我是鸭血粉丝(大家可以称呼我为「阿粉」)。今天,阿粉带着大家来了解一下获取 mapper.xml 配置文件中的sql
3591 0
让你的iOS应用程序支持运行JavaScript脚本:JavaScriptCore框架详解(二)
让你的iOS应用程序支持运行JavaScript脚本:JavaScriptCore框架详解
65 0
【剖析|SOFARPC 框架】系列之 SOFARPC 注解支持剖析
在开源 SOFARPC 版本中增加这个功能的注解支持,对服务发布和引用做了一个使用方式的补充,而对于 XML 与注解的优劣取舍,大家可以团队的规范和个人的评估进行相应的使用。
1790 0
shared pool 深度解析2+
Library cache是Shared pool的一部分,它几乎是Oracle内存结构中最复杂的一部分,主要存放shared curosr(SQL)和PLSQL对象(function,procedure,trigger)的信息,以及这些对象所依赖的table,index,view等对象的信息。
935 0
+关注
85
文章
5
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载