タイガーラック クリエイティブブログ
2025
September
18

postgresqlのPL/pgSQL関数で複数レコードをテーブル形式で出力する方法

postgresqlでSQLで取得したデータに対して加工したレコードを返したいという場合があるかと思います。
今回は関数で複数レコードをテーブル形式で出力する方法を紹介したいと思います。

テーブル

売上id顧客id
A001K001
A002K003
↑売上テーブル
売上id商品id個数
A001ringo10
A001mikan30
A002budo20
A002ringo50
↑売上明細
商品id商品名原価
ringoりんご100
mikanみかん300
budoぶどう500
↑商品マスタ

ソースコード

CREATE OR REPLACE FUNCTION get_売上値引額 ()
RETURNS TABLE (
    売上id VARCHAR,
    商品id VARCHAR,
    商品名 VARCHAR,
    個数 VARCHAR,
    原価 VARCHAR
)
AS $$
BEGIN
    RETURN QUERY
    SELECT
        a.売上id,
        a.商品id,
        a.個数,
        b.商品名,
        b.原価
    FROM 売上明細 AS a
    INNER JOIN 商品マスタ AS b 
       ON a.商品id = b.商品id
    ;
END;
$$ LANGUAGE plpgsql;

SQL

SELECT *
FROM get_売上値引額();

結果

売上id商品id個数商品名原価
A001ringo10りんご100
A001mikan30みかん300
A002budo20ぶどう500
A002ringo50りんご100

説明

RETURNS TABLE内で宣言したカラムがレコードとして返されます。
RETURN QUERYでSQLのレコードを出力します。

データを加工した場合の出力方法

上の例ではSQLで取得したレコードをそのまま返しましたが、
次にデータを加工した場合の出力方法を紹介します。

例:個数が20個を超えていた場合、10%の値引きを明細に追加する
※売上idを指定して出力するようにしてます。

ソースコード

CREATE OR REPLACE FUNCTION "public"."get_売上値引額_売上id指定"("p_売上id" text)
RETURNS TABLE (
    売上id VARCHAR,
    商品id VARCHAR,
    商品名 VARCHAR,
    個数 VARCHAR,
    原価 int4,
)
 AS $BODY$
  DECLARE
    dblamt double;
    cur cursor(p_売上id varchar) for SELECT * FROM 売上テーブル a WHERE a.売上id ~ p_売上id;
begin
    dblamt := 0;
    
    FOR cur_rec IN cur(p_売上id)
      LOOP
        売上id := cur_rec.売上id;
        商品id := cur_rec.商品id;
        商品名 := cur_rec.商品名;
        個数 := cur_rec.個数;
        原価 := cur_rec.原価;
        
        if cur_rec.個数 > 20 then
          dblamt := dblamt + ((cur_rec.原価 * cur_rec.個数) * 0.1);
        end if;
        
        RETURN NEXT;
      END LOOP;
      
      売上id := p_売上id;
      商品id := 'nebiki';
      商品名 := '値引';
      個数 := 1;
      原価 := dblamt * -1; --マイナスの金額に反転
      RETURN NEXT;
    RETURN;
end;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100
  ROWS 1000

SQL

SELECT *
FROM get_売上値引額_売上id指定('A001');

結果

売上id商品id個数商品名原価
A001ringo10りんご100
A001mikan30みかん300
A001nebiki1値引-900
明細にはないレコードを1件追加することができました。

まとめ

データ加工してテーブルとして出力するという機能は知っているとかなり便利に使えると思いますので
参考になれば幸いです。

補足

関数がテーブルで返ってくるので
SELECT *
FROM テーブル a
LEFT JOIN function() b
ON a.カラム = b.カラム
みたいな書き方も可能です。

このカテゴリの最新記事

関連記事

SHOP LIST

タイガーラック株式会社

〒577-0056
大阪府東大阪市長堂1-3-14 TOKUYASU Bld.