Lo que está tratando de hacer podría funcionar así:
Editar con información adicional
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;
Llamar:
SELECT * FROM f_products_per_month();
Puntos principales:
- Edición final para incluir una fila vacía para meses sin productos.
- Escribiste "LEFT JOIN", pero no es así como puede funcionar.
- Hay varias formas de hacer esto, pero
RETURN QUERY
es el más elegante. - Use el mismo tipo de devolución que usa su función get_forecast_history().
- Evite los conflictos de nombres con los parámetros OUT calificando los nombres de las columnas en tablas (ya no se aplica en la versión final).
- No use
DATE '2008-01-01'
, use una marca de tiempo como lo hice yo, tiene que convertirse para to_char() de todos modos. Menos lanzamiento, funciona mejor (no es que importe mucho en este caso). '2008-01-01 0:0'::timestamp
ytimestamp '2008-01-01 0:0'
son solo dos variantes de sintaxis que hacen lo mismo.- Para versiones anteriores de PostgreSQL, el lenguaje plpgsql no está instalado de forma predeterminada. Es posible que deba ejecutar
CREATE LANGUAGE plpgsql;
una vez en su base de datos. Consulte el manual aquí .
Si lo desea, probablemente podría simplificar sus dos funciones en una consulta o función.