SQL 有序计算

本文探讨了 SQL 中的有序计算,包括相邻记录引用、序号定位和有序分组。早期 SQL 解决相邻记录引用需要使用 JOIN,但随着窗口函数的引入,有序计算变得更加简便。文中通过多个实例展示了如何使用窗口函数解决股价涨幅、移动平均等计算问题,同时也指出了 SQL 在处理有序计算时的局限性和挑战。
摘要由CSDN通过智能技术生成

什么是有序计算

       使用过 SQL 的朋友对计算字段都不会陌生,比如 firstname+lastname,year(birthday),这些计算字段属于行内计算,不管表达式里用到的是单个字段,还是多个字段,使用的数据都在当前记录行内。有行内计算,对应的也就有跨行计算,如:第一名和第二名的差距;从 1 月到当前月份累计的销售额。按照成绩有序,才会有第一名、第二名的说法,累计操作同样基于有序数据,从第几个累加到第几个,这些基于有序集合的计算,就属于有序计算。行内计算关心的是每条数据自身的情况,而跨行的有序计算则关心有序数据的变化情况。

 

相邻记录引用

简单常见的有序计算是相邻记录引用,也就是在计算中要引用某种次序下的相邻记录。比如下面这些问题:

1、 股价每天的涨幅是多少(比上期)

按日期排序时,引用上一天的股价。

2、 前一天 + 当天 + 后一天的平均股价是多少(移动平均)

按日期排序时,引用前后两天的股价。

3、 多支股票数据,计算每支股票内的每日涨幅(分组内的比上期)

按股票分组,组内按日期排序,引用上一天股价。

接下来通过这几个例子研究下 SQL 如何实现这类有序计算。

早期 SQL 的解决方案

       早期的 SQL 没有窗口函数,引用相邻记录的方法是用 JOIN 把相邻记录拼到同一行。

       问题 1 写出来是这样的:

       SELECT day, curr.price/pre.price rate

       FROM (

              SELECT day, price, rownum row1

              FROM tbl ORDER BY day ASC) curr

       LEFT JOIN (

              SELECT day, price, rownum row2

              FROM tbl ORDER BY day ASC) pre

       ON curr.row1=pre.row2+1

       即将本表和本表做 JOIN,把前一天和当天作为连接条件,这样即可将前一天的股价和当天股价连接到同一行中,再用行内计算得到涨幅。一个很简单的问题必须使用子查询才能解决。

 

       再看问题 2,计算股价的移动平均,(前一天 + 当天 + 后一天)/3,同样是使用 JOIN 实现:

       SELECT day, (curr.price+pre.price+after.price)/3 movingAvg

       FROM (

              SELECT day, price, rownum row1

              FROM tbl ORDER BY day ASC) curr

       LEFT JOIN (

              SELECT day, price, rownum row2

              FROM tbl ORDER BY day ASC) pre

       ON curr.row1=pre.row2+1

       LEFT JOIN (

              SELECT day, price, rownum row3

              FROM tbl ORDER BY day ASC) after

       ON curr.row1=after.row3-1

       多取一天,就多 JOIN 一个子查询,试想,如果要计算前 10 天 ~ 后 10 天的移动平均ÿ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值