To, do czego próbujesz, może działać tak:
Edytuj z dodatkowymi informacjami
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;
Zadzwoń:
SELECT * FROM f_products_per_month();
Główne punkty:
- Ostateczna zmiana w celu uwzględnienia pustego wiersza dla miesięcy bez produktów.
- Napisałeś „LEFT JOIN”, ale to tak nie działa.
- Istnieje na to kilka sposobów, ale
RETURN QUERY
jest najbardziej elegancki. - Użyj tego samego typu zwracanego, którego używa twoja funkcja get_forecast_history().
- Unikaj konfliktów nazewnictwa z parametrami OUT przez zakwalifikowanie nazw kolumn do tabeli (nie ma już zastosowania w ostatecznej wersji).
- Nie używaj
DATE '2008-01-01'
, użyj znacznika czasu, tak jak ja, i tak musi zostać przekonwertowany na to_char(). Mniej rzucania, działa lepiej (nie ma to większego znaczenia w tym przypadku). '2008-01-01 0:0'::timestamp
itimestamp '2008-01-01 0:0'
to tylko dwa warianty składni robiące to samo.- W starszych wersjach PostgreSQL język plpgsql nie jest domyślnie instalowany. Być może będziesz musiał wydać
CREATE LANGUAGE plpgsql;
raz w Twojej bazie danych. Zobacz instrukcję tutaj .
Prawdopodobnie możesz uprościć swoje dwie funkcje w jedno zapytanie lub funkcję, jeśli chcesz.