Was Sie versuchen, könnte so funktionieren:
Mit zusätzlichen Informationen bearbeiten
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;
Aufruf:
SELECT * FROM f_products_per_month();
Hauptpunkte:
- Endgültige Bearbeitung, um eine ansonsten leere Zeile für Monate ohne Produkte einzufügen.
- Du hast "LEFT JOIN" geschrieben, aber so kann es nicht funktionieren.
- Dafür gibt es mehrere Möglichkeiten, aber
RETURN QUERY
ist am elegantesten. - Verwenden Sie denselben Rückgabetyp wie Ihre Funktion get_forecast_history().
- Vermeiden Sie Namenskonflikte mit den OUT-Parametern, indem Sie die Spaltennamen tabellarisch qualifizieren (entfällt in der finalen Version).
- Verwenden Sie
DATE '2008-01-01'
nicht , verwenden Sie einen Zeitstempel wie ich, er muss sowieso für to_char() konvertiert werden. Weniger Casting, bessere Leistung (nicht, dass es in diesem Fall viel ausmacht). '2008-01-01 0:0'::timestamp
undtimestamp '2008-01-01 0:0'
sind nur zwei Syntaxvarianten, die dasselbe tun.- Für ältere Versionen von PostgreSQL ist die Sprache plpgsql standardmäßig nicht installiert. Möglicherweise müssen Sie
CREATE LANGUAGE plpgsql;
ausführen einmal in Ihrer Datenbank. Siehe das Handbuch hier .
Sie könnten Ihre beiden Funktionen wahrscheinlich zu einer Abfrage oder Funktion vereinfachen, wenn Sie möchten.