Ce que vous essayez de faire pourrait fonctionner comme ceci :
Modifier avec des informations supplémentaires
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;
Appel :
SELECT * FROM f_products_per_month();
Points majeurs :
- Modification finale pour inclure une ligne autrement vide pendant des mois sans produits.
- Vous avez écrit "LEFT JOIN", mais ce n'est pas ainsi que cela peut fonctionner.
- Il existe plusieurs façons de procéder, mais
RETURN QUERY
est le plus élégant. - Utilisez le même type de retour que celui utilisé par votre fonction get_forecast_history().
- Évitez les conflits de nommage avec les paramètres OUT en qualifiant de table les noms de colonne (ne s'applique plus dans la version finale).
- N'utilisez pas
DATE '2008-01-01'
, utilisez un horodatage comme je l'ai fait, il doit être converti pour to_char() de toute façon. Moins de casting, plus performant (ce n'est pas si important dans ce cas). '2008-01-01 0:0'::timestamp
ettimestamp '2008-01-01 0:0'
ne sont que deux variantes de syntaxe faisant la même chose.- Pour les anciennes versions de PostgreSQL, le langage plpgsql n'est pas installé par défaut. Vous devrez peut-être émettre
CREATE LANGUAGE plpgsql;
une fois dans votre base de données. Voir le manuel ici .
Vous pourriez probablement simplifier vos deux fonctions en une seule requête ou fonction si vous le souhaitez.