1

get_forecast_history(integer,integer)月と年の 2 つの引数を取る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)。

  ym 製品の実際の
---- -- -------- ------
2011 10 製品1 29
2011 10 製品2 10
2011 10 製品3 8
2011 10 製品4 0
2011 10 製品5 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_seriesgenerate_seriesgenerate_series

PostgreSQL 8.3.14 を使用しています。

4

1 に答える 1

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();

主なポイント:

  • 製品のない月の空の行を含めるための最終編集。
  • 「LEFT JOIN」と書きましたが、それではうまくいきません。
  • これを行うにはいくつかの方法がありますRETURN QUERYが、最もエレガントです。
  • 関数 get_forecast_history() が使用するのと同じ戻り値の型を使用します。
  • 列名を表で修飾することにより、OUT パラメーターとの名前の競合を回避します (最終バージョンでは適用されなくなりました)。
  • を使用しないでくださいDATE '2008-01-01'。私が行ったようにタイムスタンプを使用してください。とにかく to_char() に変換する必要があります。キャストが少ないほど、パフォーマンスが向上します (この場合、それほど重要ではありません)。
  • '2008-01-01 0:0'::timestamptimestamp '2008-01-01 0:0'は、同じことを行う 2 つの構文バリアントにすぎません。
  • 古いバージョンの PostgreSQL では、言語 plpgsql はデフォルトではインストールされません。データベースで 1 回発行する必要がある場合がありCREATE LANGUAGE plpgsql;ます。マニュアルはこちらをご覧ください。

必要に応じて、2 つの関数を 1 つのクエリまたは関数に簡略化できます。

于 2011-10-31T15:32:00.227 に答える