Rozważ tabelę, która rejestruje wizyty
create table visits (
person varchar(10),
ts timestamp,
somevalue varchar(10)
)
Rozważ te przykładowe dane (znacznik czasu uproszczony jako licznik)
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
Usiłuję przenieść ostatnią inną niż zerową wartość osoby na wszystkie jego przyszłe wizyty, dopóki ta wartość się nie zmieni (tj. Stanie się następną wartością inną niż zero).
Oczekiwany zestaw wyników wygląda następująco:
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
Moja próba wygląda następująco:
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
Uwaga: (gdzieś wartość jest pusta) w celu sortowania przyjmuje wartość 1 lub 0, dzięki czemu mogę uzyskać pierwszą wartość inną niż null w partycji.
Powyższe nie daje mi rezultatu, którego szukam.
postgresql
window-functions
maxTrialfire
źródło
źródło
pg_dump
dane testowe zamiast wkleić dane w danych wyjściowych psql i schemat tabeli?pg_dump -t table -d database
potrzebujemy tworzenia iCOPY
poleceń.Odpowiedzi:
Następujące zapytanie osiąga pożądany wynik:
Zwróć uwagę na instrukcję null case - jeśli IGNORE_NULL był obsługiwany przez funkcje okna postgres, nie byłoby to konieczne (jak wspomniano w @ ypercubeᵀᴹ)
źródło
count(somevalue) over (...)
Problem dotyczy kategorii luk i wysp. Szkoda, że Postgres jeszcze nie wdrożył
IGNORE NULL
funkcji okna, takich jakFIRST_VALUE()
, w przeciwnym razie byłoby to proste, z prostą zmianą w zapytaniu.Prawdopodobnie istnieje wiele sposobów rozwiązania tego za pomocą funkcji okna lub rekurencyjnych CTE.
Nie jestem pewien, czy jest to najbardziej skuteczny sposób, ale rekurencyjne CTE rozwiązuje problem:
źródło