Considere una tabla que registra las visitas
create table visits (
person varchar(10),
ts timestamp,
somevalue varchar(10)
)
Considere estos datos de ejemplo (marca de tiempo simplificada 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
Estoy tratando de llevar el último valor no nulo de la persona a todas sus visitas futuras hasta que ese valor cambie (es decir, se convierta en el siguiente valor no nulo).
El conjunto de resultados esperado se ve así:
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
Mi intento se ve así:
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: el (algún valor es nulo) se evalúa a 1 o 0 con el propósito de ordenar para que pueda obtener el primer valor no nulo en la partición.
Lo anterior no me da el resultado que busco.
postgresql
window-functions
maxTrialfire
fuente
fuente
pg_dump
datos de prueba en lugar de pegar los datos en una salida psql y el esquema de la tabla?pg_dump -t table -d database
Necesitamos la creación y losCOPY
comandos.Respuestas:
La siguiente consulta logra el resultado deseado:
Tenga en cuenta la declaración de caso nulo: si IGNORE_NULL fuera compatible con las funciones de la ventana de postgres, esto no sería necesario (como lo menciona @ ypercubeᵀᴹ)
fuente
count(somevalue) over (...)
El problema está en la categoría de problemas de brechas e islas. Es una pena que Postgres aún no haya implementado
IGNORE NULL
en funciones de ventana comoFIRST_VALUE()
, de lo contrario, sería trivial, con un simple cambio en su consulta.Probablemente hay muchas maneras de resolver esto utilizando funciones de ventana o CTE recursivos.
No estoy seguro de si es la forma más eficiente, pero un CTE recursivo resuelve el problema:
fuente