Apa yang Anda coba lakukan dapat bekerja seperti ini:
Edit dengan info tambahan
CREATE OR REPLACE FUNCTION f_products_per_month()
RETURNS SETOF fcholder AS
$BODY$
DECLARE
r fcholder;
BEGIN
FOR r.y, r.m IN
SELECT to_char(x, 'YYYY')::int4 -- AS y
,to_char(x, 'MM')::int4 -- AS m
FROM (SELECT '2008-01-01 0:0'::timestamp
+ (interval '1 month' * generate_series(0,57)) AS x) x
LOOP
RETURN QUERY
SELECT * -- use '*' in this case to stay in sync
FROM get_forecast_history(r.m, r.y);
IF NOT FOUND THEN
RETURN NEXT r;
END IF;
END LOOP;
END;
$BODY$
LANGUAGE plpgsql;
Telepon:
SELECT * FROM f_products_per_month();
Poin utama:
- Pengeditan terakhir untuk menyertakan baris kosong selama berbulan-bulan tanpa produk.
- Anda menulis "LEFT JOIN", tapi bukan itu cara kerjanya.
- Ada beberapa cara untuk melakukannya, tetapi
RETURN QUERY
adalah yang paling elegan. - Gunakan jenis pengembalian yang sama seperti fungsi get_forecast_history() Anda.
- Hindari konflik penamaan dengan parameter OUT dengan membuat tabel-mengkualifikasi nama kolom (tidak berlaku lagi di versi final).
- Jangan gunakan
DATE '2008-01-01'
, gunakan stempel waktu seperti yang saya lakukan, itu harus dikonversi untuk to_char() pula. Lebih sedikit casting, berkinerja lebih baik (tidak terlalu penting dalam kasus ini). '2008-01-01 0:0'::timestamp
dantimestamp '2008-01-01 0:0'
hanyalah dua varian sintaks yang melakukan hal yang sama.- Untuk PostgreSQL versi lama, bahasa plpgsql tidak diinstal secara default. Anda mungkin harus mengeluarkan
CREATE LANGUAGE plpgsql;
sekali di database Anda. Lihat manualnya di sini .
Anda mungkin dapat menyederhanakan dua fungsi menjadi satu kueri atau fungsi jika diinginkan.