Considere uma tabela que registra visitas
create table visits (
person varchar(10),
ts timestamp,
somevalue varchar(10)
)
Considere este exemplo de dados (registro de data e hora simplificado como contador)
ts| person | somevalue
-------------------------
1 | bob |null
2 | bob |null
3 | jim |null
4 | bob | A
5 | bob | null
6 | bob | B
7 | jim | X
8 | jim | Y
9 | jim | null
Estou tentando levar adiante o último valor não nulo da pessoa para todas as suas futuras visitas até que esse valor mude (ou seja, se torne o próximo valor não nulo).
O conjunto de resultados esperado se parece com o seguinte:
ts| person | somevalue | carry-forward
-----------------------------------------------
1 | bob |null | null
2 | bob |null | null
3 | jim |null | null
4 | bob | A | A
5 | bob | null | A
6 | bob | B | B
7 | jim | X | X
8 | jim | Y | Y
9 | jim | null | Y
Minha tentativa é assim:
select *,
first_value(somevalue) over (partition by person order by (somevalue is null), ts rows between UNBOUNDED PRECEDING AND current row ) as carry_forward
from visits
order by ts
Nota: o (algum valor é nulo) é avaliado como 1 ou 0 para fins de classificação, para que eu possa obter o primeiro valor não nulo na partição.
O exposto acima não me dá o resultado que estou procurando.
postgresql
window-functions
maxTrialfire
fonte
fonte
pg_dump
dados dos seus testes em vez de colar os dados em uma saída psql e o esquema da tabela?pg_dump -t table -d database
precisamos dosCOPY
comandos create eRespostas:
A consulta a seguir alcança o resultado desejado:
Observe a declaração de caso nulo - se IGNORE_NULL fosse suportado pelas funções da janela do postgres, isso não seria necessário (como mencionado por @ ypercubeᵀᴹ)
fonte
count(somevalue) over (...)
O problema está na categoria de problemas e ilhas. É uma pena que o Postgres ainda não tenha implementado
IGNORE NULL
em funções de janela comoFIRST_VALUE()
, caso contrário, seria trivial, com uma simples alteração na sua consulta.Provavelmente existem muitas maneiras de resolver isso usando funções de janela ou CTEs recursivas.
Não tenho certeza se é a maneira mais eficiente, mas uma CTE recursiva resolve o problema:
fonte