我有一个名为get_forecast_history(integer,integer)
的SQL函数,它带有两个参数,一个月和一年。该函数返回使用以下函数创建的CUSTOM TYPE:
CREATE TYPE fcholder AS (y integer, m integer, product varchar, actual real);
函数定义的第一行是:
CREATE OR REPLACE FUNCTION get_forecast_history(integer, integer)
RETURNS SETOF fcholder AS $$
通话:
SELECT * FROM get_forecast_history(10, 2011);
例如,生成下表(函数的结果类型是一个表,即SETOF
):
y m product actual ---- -- -------- ------ 2011 10 Product1 29 2011 10 Product2 10 2011 10 Product3 8 2011 10 Product4 0 2011 10 Product5 2
等。 (总共约30种产品)。这是给定月份的历史。
我还有另一个生成一系列月份的查询:
SELECT to_char(DATE '2008-01-01'
+ (interval '1 month' * generate_series(0,57)), 'YYYY-MM-DD') AS ym
哪些产品的列表如下:
ym ---------- 2008-01-01 2008-02-01 2008-03-01 2008-04-01 ... 2011-10-01
我需要通过获取LEFT JOIN
的结果并将它们作为参数传递给函数,以某种方式generate_series
上述函数的generate_series
年/月组合的结果。这样我就可以获得函数的结果,但是对于generate_series
的每年/月组合。此时我被困住了。
我正在使用PostgreSQL 8.3.14。
答案 0 :(得分:2)
你想要的是这样的:
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;
呼叫:
SELECT * FROM f_products_per_month();
RETURN QUERY
是最优雅的。DATE '2008-01-01'
,像我一样使用时间戳,无论如何都必须转换为to_char()。减少铸造,表现更好(在这种情况下并不重要)。'2008-01-01 0:0'::timestamp
和timestamp '2008-01-01 0:0'
只是两种语法变体。CREATE LANGUAGE plpgsql;
。见the manual here。如果需要,您可以将两个函数简化为一个查询或函数。