matomomomemo

PostgreSQLのgenerate_series関数について

概要

  • https://www.postgresql.jp/docs/16/functions-srf.html
  • 連続した値を生成することができる関数

インターフェース

  • 利用可能な型
    • 数値
    • タイムスタンプ

数値

  • 引数
    • 始点
    • 終点
    • 増加/減少幅(optional)
      • default: 1
  • 戻り値
    • 数値の集合

タイムスタンプ

  • 引数
    • 始点
    • 終点
    • 増加/減少幅
    • タイムゾーン(optional)
      • default: 現在設定されているタイムゾーンが利用される
  • 戻り値
    • タイムスタンプの集合

FROM句で使う

数値

  • 1から3までの数値を増加幅1で数値を生成する
SELECT * FROM generate_series(1,3);
 generate_series 
-----------------
               1
               2
               3
  • 1から3までの数値を増加幅2で数値を生成する
SELECT * FROM generate_series(1,3,2);
 generate_series 
-----------------
               1
               3
  • 3から1までの数値を減少幅1で数値を生成する
SELECT * FROM generate_series(3,1,-1);
 generate_series 
-----------------
               3
               2
               1

タイムスタンプ

  • 2025/01/01~2025/01/02で、3時間ごとのタイムスタンプを生成する
SELECT * FROM generate_series('2025-01-01 00:00'::timestamp,'2025-01-02 00:00', '3 hours');
   generate_series   
---------------------
 2025-01-01 00:00:00
 2025-01-01 03:00:00
 2025-01-01 06:00:00
 2025-01-01 09:00:00
 2025-01-01 12:00:00
 2025-01-01 15:00:00
 2025-01-01 18:00:00
 2025-01-01 21:00:00
 2025-01-02 00:00:00

SELECT句で使う

  • 1から3までの数値を増加幅1で数値を生成する
    • FROM句で利用する場合と同等のデータが作れそう
SELECT generate_series(1, 3) AS i;
 i 
---
 1
 2
 3
  • 2025/01/01から4日間の日付を生成する
SELECT '2025-01-01'::date + generate_series(0, 3) AS date;
    date    
------------
 2025-01-01
 2025-01-02
 2025-01-03
 2025-01-04

SELECT句+FROM句で使う

  • 2025/01/01から4日間の日付を3つずつ生成する
    • SELECT句のgenerate_series と FROM句のgenerate_seriesを掛け合わせたデータが生成される
SELECT '2025-01-01'::date + generate_series(0, 3) AS date, i FROM generate_series(0, 2) i;
    date    | i 
------------+---
 2025-01-01 | 0
 2025-01-02 | 0
 2025-01-03 | 0
 2025-01-04 | 0
 2025-01-01 | 1
 2025-01-02 | 1
 2025-01-03 | 1
 2025-01-04 | 1
 2025-01-01 | 2
 2025-01-02 | 2
 2025-01-03 | 2
 2025-01-04 | 2

INSERT文で使う

  • 2025/01/01から4日間の日付とそれぞれのランダムな数値を、3つのcodeごとに生成する
    • generate_seriesで生成したデータをINSERT文のVALUESとして利用する
INSERT INTO mytbl (p_code, "date", t_value)
SELECT
    i,
    '2024-01-01'::date + generate_series(0, 3),
    random() * 100
FROM generate_series(0, 2) i
;