カテゴリー
コンピューター

【PostgreSQL】PL/pgSQL を使わずに 1 回の SQL でループを実現する方法

まとめ

  • WITH RECURSIVE を使う。
  • ループでない時と比べて性能が向上または劣化するかは検証していない。
  • ループの中身を UNION ALL で繋げたものと比べると、順番が異なっていたときがあった気がする(うろ覚え)。下例のループ内部分に ORDER BY をつけて制御する。

以下は、公式ページの例に解説を加えた、シンプルな例です。

-- ループ定義部分
-- n がループ要素の変数
WITH RECURSIVE t(n) AS (
    VALUES (1)
  -- 重複を排除せずに結果に追加
  UNION ALL
    -- 100 未満まで n をインクリメント
    SELECT n+1 FROM t WHERE n < 100
)
-- ループ内部分
SELECT sum(n) FROM t;

実際の使い方

テーブルからの SELECT で、日付部分のみを少しだけ変えて同じような SQL を実行したい例です。

  • テーブルから値を取りたいときは、FROM 句でカンマでテーブルを並べればよい。
WITH RECURSIVE loop(i) AS (
  VALUES (1)
  UNION ALL
  SELECT i + 1 FROM loop WHERE i < 10
)
SELECT 
  date_part('year', make_date(2018, 4, 1) + CAST(i || ' month' AS interval) AS year
  , date_part('month', make_date(2018, 4, 1) + CAST(i || ' month' AS interval) AS month
FROM loop;

おわりに

次のページが、参考になりました!ありがとう存じます!

以上です。

コメントを残す