Pertanyaan lengkap tulis ulang
Saya mencari fungsi agregat First ().
Di sini saya menemukan sesuatu yang hampir berfungsi:
CREATE OR REPLACE FUNCTION public.first_agg ( anyelement, anyelement )
RETURNS anyelement LANGUAGE sql IMMUTABLE STRICT AS $$
SELECT $1;
$$;
-- And then wrap an aggregate around it
CREATE AGGREGATE public.first (
sfunc = public.first_agg,
basetype = anyelement,
stype = anyelement
);
Masalahnya adalah bahwa ketika kolom varchar (n) melewati fungsi first (), itu diubah menjadi varchar sederhana (tanpa ukuran). Mencoba mengembalikan kueri dalam fungsi sebagai RETURNS SETOF anyelement, saya mendapatkan kesalahan berikut:
GALAT: struktur kueri tidak cocok dengan tipe hasil fungsi Estado de SQL: 42804 Detalhe: Pengubahan karakter tipe yang dikembalikan tidak cocok dengan variasi tipe karakter yang diharapkan (40) di kolom 2. Konteks: Fungsi PL / pgSQL vsr_table_at_time (anyelement, timestamp tanpa zona waktu) ) baris 31 di KEMBALI QUERY
Di halaman wiki yang sama ada tautan ke Versi C dari fungsi yang akan menggantikan yang di atas. Saya tidak tahu cara menginstalnya, tetapi saya ingin tahu apakah versi ini dapat menyelesaikan masalah saya.
Sementara itu, apakah ada cara saya dapat mengubah fungsi di atas sehingga mengembalikan jenis kolom input yang sama persis?
sumber
DISTINCT ON
tidak akan berfungsi dalam kasus ini. Ini bukan fungsi agregat, Anda sebenarnya memfilter data dan jadi Anda hanya bisa melakukannya sekali.Yay, saya sudah menemukan cara mudah dengan kasing Anda dengan menggunakan beberapa fitur di PostgreSQL 9.4+
Mari kita lihat contoh ini:
Saya harap ini akan membantu Anda dalam kasus Anda.
sumber
DOMAIN
tipe data, atau pengecualian kecil lainnya. Ini juga jauh lebih kompleks dan memakan waktu, membangun sebuah array dari seluruh kumpulan data. Solusi sederhananya adalah membuat agregat khusus, tetapi sejauh ini saya belum menemukan solusi ideal bahkan dengan itu. Fungsi jendela juga buruk, karena tidak dapat digunakan dengan cara yang sama seperti Anda dapat menggunakan agregat (dengan pernyataan FILTER, atau dalam CROSS JOIN LATERAL)Bukan jawaban langsung untuk pertanyaan Anda tetapi Anda harus mencoba
first_value
fungsi jendela. Ini berfungsi seperti ini:);
Kemudian, jika Anda menginginkan item pertama di setiap
cat
(kategori) Anda akan meminta seperti itu:atau:
sumber
select distinct x, first_value(y) over (partition by x), first_value(z) over (partition by x) from ...
. Mungkin tidak efisien tetapi cukup bagi saya untuk melanjutkan pembuatan prototipe. Pasti sesuatu untuk ditinjau kembali!