基于历史结果计算的 SQL 语句怎么写

我想计算一个仓位列,比如叫position,初始为0,当(position = 0, ov95 = 1)的时候position变成1, 当(position = 1, ov70 = 0)的时候 position 变成0

attachments-2023-11-25EaZo6g65571a4bc1955.png


这个有办法用sql实现吗? 这里相当于是算第k行的position需要第k-1行position的值。

请先 登录 后评论

2 个回答

veryOrdinary

可以利用 accumulate 进行迭代运算:

ov95 = 1 1 1 0 0 0 0 0 0
ov97 = 0 0 0 0 0 0 1 1 1
t = table(ov95, ov70)
def myf(pos, ov95, ov70): iif(pos==0 and ov95 == 1, 1, iif(pos==1 and ov70 == 0, 0, pos))
select ov95, ov70, accumulate(myf, [ov95, ov70], 0) as pos from t
请先 登录 后评论
NA

假设有一个表如下:

time = 2023.01.01T09:00:00.000 + 1..9
code = take(`a, 9)
ov95 = 1 1 1 0 0 0 0 0 0
ov70 = 0 0 0 0 0 0 1 1 1
t = table(time, code, ov95, ov70)

现需要计算指标 position,公式如下:

attachments-2024-01-AjgyatO165b8b612df13e.png
则可以用以下方式实现

方案一:accumulate

res = select *, accumulate(def(pos, ov95, ov70):iif(pos==0&&ov95 == 1, 1, iif(pos==1&&ov70 == 0, 0, pos)), [ov95, ov70], 0) as pos from t

方案二:for 循环+JIT

@jit
def calPos(ov95, ov70){
	pos = array(INT, size(ov95)+1)
	for(i in 0:size(ov95)){
		if(pos[i]==0&&ov95[i]==1)	pos[i+1]=1
		else if(pos[i]==1&&ov70[i]==0)	pos[i+1]=0
		else pos[i+1]=pos[i]
	}
	return pos[1..size(ov95)]
}

res = select *, calPos(ov95, ov70) as pos from t


性能测试测试数据:1000000*4 【38 MB】的内存表

attachments-2024-01-7mTbBgyC65b8b781f28fb.png

数据构造脚本

n = 1000000
time = 2023.01.01T09:00:00.000 + 1..n
code = take(`a, n)
ov95 = rand([0, 1], n)
ov70 = rand([0, 1], n)
t = table(time, code, ov95, ov70)


请先 登录 后评论
  • 2 关注
  • 0 收藏,407 浏览
  • Polly 提出于 2023-11-17 15:47

相似问题