Рассмотрим таблицу, в которой записываются посещения
create table visits (
person varchar(10),
ts timestamp,
somevalue varchar(10)
)
Рассмотрим данные этого примера (временная метка упрощена как счетчик)
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
Я пытаюсь перенести последнее ненулевое somevalue человека на все его будущие посещения, пока это значение не изменится (то есть не станет следующим ненулевым) значением.
Ожидаемый набор результатов выглядит следующим образом:
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
Моя попытка выглядит так:
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
Примечание: (somevalue равно null) оценивается как 1 или 0 для целей сортировки, поэтому я могу получить первое ненулевое значение в разделе.
Выше не дает мне результат, который я после.
postgresql
window-functions
maxTrialfire
источник
источник
pg_dump
данные теста, а не вставить данные в вывод psql и схему для таблицы?pg_dump -t table -d database
нам нужны команды create иCOPY
.Ответы:
Следующий запрос достигает желаемого результата:
Обратите внимание на нулевой регистр - если IGNORE_NULL поддерживается оконными функциями postgres, в этом нет необходимости (как упоминалось в @ ypercubeᵀᴹ)
источник
count(somevalue) over (...)
Проблема в категории проблем с пробелами и островами. Жаль, что Postgres еще не реализовал
IGNORE NULL
в окнах такие функции, какFIRST_VALUE()
, иначе, это было бы тривиально, с простым изменением в вашем запросе.Вероятно, есть много способов решить эту проблему с помощью оконных функций или рекурсивных CTE.
Не уверен, что это самый эффективный способ, но рекурсивный CTE действительно решает проблему:
источник