如何根据前几行创建列?
How to create column based on previous rows?
我有以下 table:
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
我知道我需要 window 函数,但我不知道 window 函数如何引用 "in progress" 的列,基本上 window 函数需要引用 type
和 new_type
但 new_type
还不存在。这是输出。
如何在 SQL / Presto 中完成?
How can this be done in 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 全面支持 window 功能。在这里,您可以使用 lag()
和 ignore nulls
选项来替换 type
列中的 null
值:
select
id,
type,
coalesce(
type,
lag(type ignore nulls) over(order by id)
) new_type
from mytable
需要一个游标,尤其是当 id 不能保证顺序且没有间隙时。
这将 运行 在 MS-SQL:
-- stage sample data
drop table if exists oldTable
create table oldTable (id int, old_type nvarchar(1))
go
insert into oldTable values (1, null), (2, 'A'), (3, null), (4, null), (5, 'A'), (6, null), (7, 'B'), (8, 'A'), (9, 'B'), (10, null)
go
-- get new table ready
drop table if exists newTable
create table newTable (
id int,
old_type nvarchar(1),
new_type nvarchar(1)
)
GO
-- prepare for lots of cursing
declare @the_id int
declare @the_type nvarchar(1)
declare @running_type nvarchar(1)
declare mycursor cursor for
select
id, old_type
from
oldTable
-- do a barrel roll
open mycursor
fetch mycursor into @the_id, @the_type
while @@ERROR = 0 and @@FETCH_STATUS = 0
begin
set @running_type = COALESCE(@the_type, @running_type)
insert into newTable(id, old_type, new_type)
values (@the_id, @the_type, @running_type)
fetch mycursor into @the_id, @the_type
end
close mycursor
deallocate mycursor
go
-- verify results
select * from newTable
go
我有以下 table:
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
我知道我需要 window 函数,但我不知道 window 函数如何引用 "in progress" 的列,基本上 window 函数需要引用 type
和 new_type
但 new_type
还不存在。这是输出。
如何在 SQL / Presto 中完成?
How can this be done in 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 全面支持 window 功能。在这里,您可以使用 lag()
和 ignore nulls
选项来替换 type
列中的 null
值:
select
id,
type,
coalesce(
type,
lag(type ignore nulls) over(order by id)
) new_type
from mytable
需要一个游标,尤其是当 id 不能保证顺序且没有间隙时。
这将 运行 在 MS-SQL:
-- stage sample data
drop table if exists oldTable
create table oldTable (id int, old_type nvarchar(1))
go
insert into oldTable values (1, null), (2, 'A'), (3, null), (4, null), (5, 'A'), (6, null), (7, 'B'), (8, 'A'), (9, 'B'), (10, null)
go
-- get new table ready
drop table if exists newTable
create table newTable (
id int,
old_type nvarchar(1),
new_type nvarchar(1)
)
GO
-- prepare for lots of cursing
declare @the_id int
declare @the_type nvarchar(1)
declare @running_type nvarchar(1)
declare mycursor cursor for
select
id, old_type
from
oldTable
-- do a barrel roll
open mycursor
fetch mycursor into @the_id, @the_type
while @@ERROR = 0 and @@FETCH_STATUS = 0
begin
set @running_type = COALESCE(@the_type, @running_type)
insert into newTable(id, old_type, new_type)
values (@the_id, @the_type, @running_type)
fetch mycursor into @the_id, @the_type
end
close mycursor
deallocate mycursor
go
-- verify results
select * from newTable
go