Pertimbangkan tabel yang mencatat kunjungan
create table visits (
person varchar(10),
ts timestamp,
somevalue varchar(10)
)
Pertimbangkan contoh data ini (stempel waktu disederhanakan sebagai penghitung)
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
Saya mencoba meneruskan nilai non-null terakhir dari orang tersebut ke semua kunjungannya di masa mendatang hingga nilai tersebut berubah (yaitu menjadi nilai non-nol berikutnya).
Kumpulan hasil yang diharapkan terlihat seperti ini:
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
Usaha saya terlihat seperti ini:
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
Catatan: the (somevalue is null) mengevaluasi ke 1 atau 0 untuk keperluan penyortiran sehingga saya bisa mendapatkan nilai non-null pertama di partisi.
Di atas tidak memberi saya hasil yang saya kejar.
postgresql
window-functions
maxTrialfire
sumber
sumber
pg_dump
untuk data pengujian Anda daripada menempelkan data dalam output psql, dan skema untuk tabel?pg_dump -t table -d database
kita membutuhkan perintah create danCOPY
.Jawaban:
Kueri berikut mencapai hasil yang diinginkan:
Catat pernyataan kasus nol - jika IGNORE_NULL didukung oleh fungsi jendela postgres, ini tidak diperlukan (seperti yang disebutkan oleh @ ypercubeᵀᴹ)
sumber
count(somevalue) over (...)
Masalahnya adalah dalam kategori masalah kesenjangan dan pulau. Sangat disayangkan bahwa Postgres belum diimplementasikan
IGNORE NULL
dalam fungsi-fungsi jendela sepertiFIRST_VALUE()
, kalau tidak itu akan sepele, dengan perubahan sederhana dalam kueri Anda.Mungkin ada banyak cara untuk ini diselesaikan menggunakan fungsi jendela atau CTE rekursif.
Tidak yakin apakah itu cara yang paling efisien tetapi CTE rekursif dapat menyelesaikan masalah:
sumber