Как создать столбец на основе предыдущих строк? - PullRequest
3 голосов
/ 29 января 2020

У меня есть следующая таблица:

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

Я знаю, что мне нужна здесь оконная функция, но я не знаю, как оконная функция может ссылаться на столбец, который находится "в процессе", в основном оконная функция должна ссылаться на оба type и new_type, но new_type еще не существует ... это вывод.

Как это можно сделать в SQL / Presto?

Ответы [ 3 ]

2 голосов
/ 29 января 2020

Presto имеет всестороннюю поддержку оконных функций. Здесь вы можете использовать lag() с опцией ignore nulls для замены null значений в столбце type:

select 
    id,
    type,
    coalesce(
        type,
        lag(type ignore nulls) over(order by id)
    ) new_type
from mytable
2 голосов
/ 29 января 2020

Требуется курсор, особенно если идентификатор не гарантирует, что он будет последовательным и без пробелов.

Это будет работать в 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
1 голос
/ 29 января 2020

Как это можно сделать в 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
...