Sql 如何基于上一行创建列?

Sql 如何基于上一行创建列?,sql,window-functions,presto,Sql,Window Functions,Presto,我有下表: id type 1 NULL 2 A 3 NULL 4 NULL 5 A 6 NULL 7 B 8 A 9 B 10 NULL 我想创建一个列,其中每一行都采用当前状态(如果存在),如果不采用前一行的状态。 基本上我想得到这个: id type new_type 1 NULL NULL -- firs one no previous so it can only be null 2 A A

我有下表:

id  type
1   NULL
2    A
3   NULL
4   NULL
5    A
6   NULL
7    B
8    A
9    B
10   NULL
我想创建一个列,其中每一行都采用当前状态(如果存在),如果不采用前一行的状态。 基本上我想得到这个:

id  type   new_type
1   NULL    NULL   -- firs one no previous so it can only be null
2    A       A     -- current type A so take it
3   NULL     A     -- no type so take the new_type of previous
4   NULL     A
5    A       A
6   NULL     A
7    B       B
8    A       A
9    B       B
10   NULL    B
我知道这里需要窗口函数,但我不知道窗口函数如何引用正在进行的列基本上窗口函数需要引用类型和新类型,但新类型还不存在。。这是输出

如何在SQL/Presto中实现这一点

如何在SQL中实现这一点

例如,它可以是

SELECT t1.id,
       t1.type,
       ( SELECT t2.type
         FROM sourcetable t2
         WHERE t2.id <= t1.id
           AND t2.type IS NOT NULL
         ORDER BY id DESC
         LIMIT 1 ) new_type
FROM sourcetable t1

Presto全面支持窗口功能。在这里,您可以使用带有ignore nulls选项的lag替换列类型中的null值:


需要一个光标,特别是当不能保证id是连续的且没有间隙时

这将在MS-SQL中运行:

-阶段样本数据 如果存在旧表,则删除该表 创建表oldTable id int,旧类型nvarchar1 去 在旧表中插入值1,null,2,'A',3,null,4,null,5,'A',6,null,7,'B',8,'A',9,'B',10,null 去 -准备好新桌子 如果存在新表,则删除表 创建新表 id int, 旧型nvarchar1, 新型nvarchar1 去 -为诅咒做好准备 声明@the_id int 声明@the_类型nvarchar1 声明@running_类型nvarchar1 将mycursor声明为 选择 id,旧类型 从…起 旧桌子 -滚桶 打开我的光标 将mycursor提取到@the_id,@the_type 而@@ERROR=0和@@FETCH\u STATUS=0 开始 设置@running\u类型=COALESCE@the_type,@running_类型 插入newTableid、旧类型、新类型 值@the_id、@the_type、@running_type 将mycursor提取到@the_id,@the_type 终止 关闭我的光标 取消分配我的游标 去 -验证结果 从newTable中选择* 去
select 
    id,
    type,
    coalesce(
        type,
        lag(type ignore nulls) over(order by id)
    ) new_type
from mytable