从 SQL 到 SPL:生成指定时间间隔内的事件次序号

MSSQL 数据库某表有三个字段:账号、字符串类型的日期和时间。

Account_Number

FuelPurchase_Date

Fuel_TOD

19

2024-04-03

07:02:02 AM

19

2024-04-03

07:02:41 AM

19

2024-04-03

02:58:49 PM

19

2024-04-03

07:58:49 PM

19

2024-04-05

02:58:49 PM

19

2024-04-05

02:59:31 PM

19

2024-04-17

11:56:13 PM

20

2024-04-17

11:59:13 PM

19

2024-04-18

12:15:13 AM

19

2024-04-18

02:56:13 PM

20

2024-04-18

07:41:55 AM

20

2024-04-18

07:41:55 PM

20

2024-04-18

07:56:55 PM

19

2024-04-19

07:41:55 AM

19

2024-04-19

07:42:20 AM

19

2024-04-19

08:41:20 AM

现在要新增一个分组的序号列 Seq,当某个账号在一个小时内发生新事件时,Seq+1;如果一个小时后才发生新事件,则重置 Seq 为 1。

Account_Number

FuelPurchase_Date

Fuel_TOD

Seq

19

2024-04-03

07:02:02 AM

1

19

2024-04-03

07:02:41 AM

2

19

2024-04-03

02:58:49 PM

1

19

2024-04-03

07:58:49 PM

1

19

2024-04-05

02:58:49 PM

1

19

2024-04-05

02:59:31 PM

2

19

2024-04-17

11:56:13 PM

1

19

2024-04-18

12:15:13 AM

2

19

2024-04-18

02:56:13 PM

1

19

2024-04-19

07:41:55 AM

1

19

2024-04-19

07:42:20 AM

2

19

2024-04-19

08:41:20 AM

3

20

2024-04-17

11:59:13 PM

1

20

2024-04-18

07:41:55 AM

1

20

2024-04-18

07:41:55 PM

1

20

2024-04-18

07:56:55 PM

2

在相对位置引用集合成员时,SQL要写成繁琐的窗口函数,经常还会多层嵌套;序号计算的逻辑判断也较为复杂,会涉及多层case when的形式,代码很繁琐。序号要在指定区间内累计,这要把这些区间拼成分组的形式,或在case when里嵌套窗口函数,思路会非常绕。

也可以在循环中引用相对位置的集合成员并进行逻辑判断,但SQL不支持循环结构,要用存储过程实现,结构就变得复杂了。

SPL支持完整的过程性语法,可以在循环中处理复杂的业务逻辑,还可以方便地用相对位置引用集合成员。


 A

1

=mssql.query("select *,cast(FuelPurchase_Date as datetime) + cast(Fuel_TOD as datetime) as DT from tb order by Account_Number,DT”)

2

=A1.new(Account_Number,FuelPurchase_Date,Fuel_TOD,

if(Account_Number==Account_Number[-1] && interval@s(Fuel_DT[-1],Fuel_DT)<3600,Seq[-1]+1,1):Seq)

A1:通过JDBC查询数据库,拼出日期时间类型的计算列DT,并按账号和DT排序。

A2:新建二维表,增加新计算列Seq。当前记录的账号与上一条记录相同,且时间间隔一小时内时,Seq+1;否则将Seq重置为1[-1]表示相对位置的上一条记录。

问题来源:https://stackoverflow.com/questions/78380050/creating-sequence-numbers-with-hourly-reset