Considérons un tableau qui enregistre les visites
create table visits (
person varchar(10),
ts timestamp,
somevalue varchar(10)
)
Considérez cet exemple de données (horodatage simplifié comme compteur)
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
J'essaie de reporter la dernière valeur non nulle de la personne à toutes ses visites futures jusqu'à ce que cette valeur change (c'est-à-dire devienne la prochaine valeur non nulle).
L'ensemble de résultats attendu ressemble à ceci:
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
Ma tentative ressemble à ceci:
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
Remarque: la (une valeur est nulle) est évaluée à 1 ou 0 pour le tri afin que je puisse obtenir la première valeur non nulle dans la partition.
Ce qui précède ne me donne pas le résultat que je recherche.
postgresql
window-functions
maxTrialfire
la source
la source
pg_dump
pour vos données de test plutôt que de coller les données dans une sortie psql et le schéma de la table?pg_dump -t table -d database
nous avons besoin de la création et desCOPY
commandes.Réponses:
La requête suivante atteint le résultat souhaité:
Notez la déclaration null case - si IGNORE_NULL était pris en charge par les fonctions de fenêtre postgres, cela ne serait pas nécessaire (comme mentionné par @ ypercubeᵀᴹ)
la source
count(somevalue) over (...)
Le problème se situe dans la catégorie des lacunes et des îles. C'est dommage que Postgres n'ait pas encore implémenté
IGNORE NULL
de fonctions de fenêtres commeFIRST_VALUE()
, sinon ce serait trivial, avec un simple changement dans votre requête.Il existe probablement de nombreuses façons de résoudre ce problème en utilisant des fonctions de fenêtre ou des CTE récursifs.
Je ne sais pas si c'est le moyen le plus efficace mais un CTE récursif résout le problème:
la source