【和SQL对比】对分组子集做跨行运算
找出发生过连续三交易日涨停(涨幅>=10%)的股票
SQL解法
with A as
(select 代码,交易日,
收盘价/lag(收盘价) over(partition by 股票
order by 交易日)-1 涨幅
from 股价表),
B as
(select 代码,
case when 涨幅>=0.1 and
lag(涨幅) over(partition by 代码
order by 交易日)>=0.1 and
lag(涨幅,2) over(partition by 代码
order by 交易日)>=0.1
then 1 else 0 end 三天连涨标志
from A)
select distinct 代码 from B where 三天连涨标志=1
窗口函数可以计算出涨幅,再对涨幅施用窗口函数可计算出三天连涨标志,经过多层嵌套后终于可以计算出结果,多了一层分组导致复杂度陡增,还好有with把嵌套SQL写成分步计算的样子。
SPL解法
| A | B | C | D | |
| 1 | =demo.query(“select * from 股价表”).group(代码).(~.sort(交易日期)) | =[] | 结果集在C1 | |
| 2 | for A1 | =0 | ||
| 3 | if A2.pselect(B2=if(close_price/close_price[-1]>=1.1,B2+1,0):3)>0 | 有三天涨停 | ||
| 4 | >C1=C1|A2.代码 | |||
或用子计算语句
| A | B | |
| 1 | =股价表.group(代码).(~.sort(交易日期)) | |
| 2 | ==A1.select(?) | =0 |
| 3 | =~.pselect(B2=if(收盘价/收盘价[-1]>=1.1,B2+1,0):3)>0 | |
| 4 | =A2.(代码) | |
天然可分步计算的SPL在多一层分组时复杂度增加有限,使用子计算语句或循环将外层剥开,内层计算就如同平时层数少的情况一样,不会带来思维上的困难。
这段代码很容易扩展成寻找有n天连续涨停,而且找到第一个连续涨停日就停止计算剩下的涨幅,相比之下,SQL的写法则很难扩展,同时窗口函数还要求必须把所有跨行计算全部算完后才能过滤。
