从 SQL 到 SPL:根据连续值生成计算列

某库表的字段 n 用于排序,x 字段是整数,有时会出现连续的 0。

n

x

1

0

2

1

3

2

4

3

5

4

6

2

7

1

8

0

9

1

10

0

11

0

12

0

13

0

14

1

15

2

16

3

17

4

现在要新增计算列 def,要求是:def 初值为 0;如果当前行 x > 2,则 将 def 置为 1;遇到 3 个连续的 x=0 时,将当前 def 重置为 0;其他情况保持 def 与上一行相同。

n

x

def

1

0

0

2

1

0

3

2

0

4

3

1

5

4

1

6

2

1

7

1

1

8

0

1

9

1

1

10

0

1

11

0

1

12

0

0

13

0

0

14

1

0

15

2

0

16

3

1

17

4

1

SQL

with cte as (
    select *
      ,(x > 2) exceeded_2
      ,(0 = all(array[     x
                      ,lag(x,1,0)over w1
                      ,lag(x,2,0)over w1
                     ]
                )
        ) as should_switch
    from have
    window w1 as (order by n) )
,cte2 as (
    select *,sum(should_switch::int)over(order by n) def_on_period 
    from cte
)
select n,x,(bool_or(exceeded_2) over w2)::int as def
from cte2
window w2 as (partition by def_on_period 
              order by n);

SQL要用多个窗口函数 + 多个子查询实现相对位置计算,代码复杂难懂。SPL 提供了表达相对位置的语法: https://try.esproc.com/splx?4OY


 A

1

$select n, x, null as def from have.txt order by n

2

=A1.run(def=if( x>2:1, x[-2]+x[-1]+x==0:0; def[-1] ))

A1:加载数据,新增空的计算列。

A2:修改计算列,如果当前行 x>2,则 def 置为 1;如果连续 3 行都是 0,则 def 置为 0;否则 def 保持不变(置为上一行的 def)。[-1] 表示上一行。

问题来源:https://stackoverflow.com/questions/78128488/values-based-on-preceding-rows-when-x2-then-repeat-1-when-x-0-for-3-consecuti