面向集合的思维编写SQL(2-移动累积值)

浏览: 1600

上一篇初步的介绍了一下面向集合思维编写SQL实现开窗函数的功能;

在这里也稍微介绍一下另外一种编写SQL的思维—面向过程,例如Oracle的PL/SQL,作为一种过程化的语言,以赋值、条件分支、循环等作为基本处理单元,并将系统整体分割成很多这样的单元的思维方式,在我看来,这更偏向于开发工作者。

确实Oracle和MSSQL这两种付费的数据库,有大量的高级函数去简化数据工作,这二者也广泛应用于商业智能领域。那么离开这些付费的产品工具,我们仅依靠着SQL和关系型数据库的原理又能在数据的世界中走多远呢?


1.场景与需求

我们有如下的一张表,date字段记录了交易日期,amt字段记录了交易金额,如下图:

image.png

现在我们要计算一个移动累计值,即计算当前行与其前面两行,一共是三行的和,如下图:

image.png

2.SQL实现:

若使用Oracle或者MSSQL,我们使用开窗函数可以很容易的实现:

image.png

那么摆脱工具的束缚,我们使用SQL进行如下的尝试:

image.png

结果如下:

image.png

3.SQL解读:

层层括号嵌套下,A3.date作为核心和代码的起始点,进行逐行的偏移,且始终在[A2.date,A3.date]内进行移动,并控制参与求和的记录集合始终在三条以内。

这里留下一个小问题,如果累积不满三行不做累加计算,也就是第一行记录与第二行记录不产生累加,如下图:

image.png

那么如何编写SQL呢?


/*原创,转载请联系!*/

推荐 1
本文由 Max_Leo 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

1 个评论

2.SQL实现部分
马老师,有些疑问请教,表A3的count(*)是作为控制A2条数的存在,但好像没法保证A2 sum的结果集就是当前行及其前面两条数据

3.SQL解读
在A3中使用having限制条数
select count(*) from m_sum A3
where A3.date between A2.date and A1.date) <=3
having count(*) > 2

要回复文章请先登录注册