お知らせ
2023.12.5(Tue)
目次
こんにちは。関口です。
SQLでデータを抽出する際に、取得元のデータは歯抜けになっているけれど、固定件数分取得したい場面って結構ありますよね。今回はそんな時に便利なGENERATE_SERIES関数の使い方を紹介していきます!
検証で使用した環境は以下の通りです。
GENERATE_SERIES関数とは、集合を返す関数です。連続した値を生成することができます。まずは文法を紹介します。
GENERATE_SERIES(start, stop, step)
startには生成する連続値の最初の値を設定します。stopには生成する連続値の最後の値を設定します。stepには生成する連続値の刻み幅を設定します。stepは省略可能で、省略した場合は刻み1で連続値を生成します。いずれもint型または、bigint型です。
では早速使ってみましょう! まずは基本の形として、1から100の連続値を生成してみます。
// 実行SQL SELECT GENERATE_SERIES(1, 100); // 実行結果 generate_series ----------------- 1 2 3 4 5 ~~~中略~~~ 97 98 99 100 (100 行)
今度はstep(刻み幅)を設定して、1から100の中から奇数だけを取得してみましょう。
// 実行SQL SELECT * FROM GENERATE_SERIES(1, 100, 2); // 実行結果 generate_series ----------------- 1 3 5 7 9 ~~~中略~~~ 93 95 97 99 (50 行)
さて、同じ要領で今度は連続した日付を生成してみましょう! 今日から10日後までの日付を取得します。
// 実行SQL SELECT * FROM GENERATE_SERIES(NOW(), NOW() + CAST('10 DAYS' AS INTERVAL), '1 DAY'); // 実行結果 generate_series ------------------------------- 2021-12-27 13:18:52.742578+09 2021-12-28 13:18:52.742578+09 2021-12-29 13:18:52.742578+09 2021-12-30 13:18:52.742578+09 2021-12-31 13:18:52.742578+09 2022-01-01 13:18:52.742578+09 2022-01-02 13:18:52.742578+09 2022-01-03 13:18:52.742578+09 2022-01-04 13:18:52.742578+09 2022-01-05 13:18:52.742578+09 2022-01-06 13:18:52.742578+09 (11 行)
いままでの応用として、既存テーブルと結合して歯抜けデータを固定件数分取得してみましょう!今回使用するテストテーブルはこちら。
SELECT * FROM test_table; id | target_date | type_code | feeling ----+-------------+-----------+-------------- 1 | 2021-12-28 | 1 | 愉快 2 | 2021-12-28 | 2 | 集中 3 | 2021-12-29 | 2 | 忙しい 4 | 2021-12-30 | 1 | 穏やか 5 | 2021-12-30 | 2 | ゆっくりする 6 | 2021-12-31 | 1 | 嬉しい 7 | 2022-01-01 | 1 | お祭り気分 8 | 2022-01-01 | 2 | 幸せ 9 | 2022-01-03 | 1 | 希望に満ちた 10 | 2022-01-04 | 2 | 気楽 (10 行)
// 実行SQL SELECT generate.g_date , generate.g_type_code , tt.feeling FROM ( SELECT CAST(g_date AS DATE) , g_type_code FROM GENERATE_SERIES(NOW(), NOW() + CAST('10 DAYS' AS INTERVAL), '1 DAY') AS g_date CROSS JOIN GENERATE_SERIES(1,2) AS g_type_code ) generate LEFT JOIN test_table AS tt ON tt.target_date = generate.g_date AND tt.type_code = generate.g_type_code ORDER BY generate.g_date , generate.g_type_code ; // 実行結果 g_date | g_type_code | feeling ------------+-------------+-------------- 2021-12-27 | 1 | 2021-12-27 | 2 | 2021-12-28 | 1 | 愉快 2021-12-28 | 2 | 集中 2021-12-29 | 1 | 2021-12-29 | 2 | 忙しい 2021-12-30 | 1 | 穏やか 2021-12-30 | 2 | ゆっくりする 2021-12-31 | 1 | 嬉しい 2021-12-31 | 2 | 2022-01-01 | 1 | お祭り気分 2022-01-01 | 2 | 幸せ 2022-01-02 | 1 | 2022-01-02 | 2 | 2022-01-03 | 1 | 希望に満ちた 2022-01-03 | 2 | 2022-01-04 | 1 | 2022-01-04 | 2 | 気楽 2022-01-05 | 1 | 2022-01-05 | 2 | 2022-01-06 | 1 | 2022-01-06 | 2 | (22 行)
いかがでしたでしょうか。
もっと応用すれば、テストデータを生成することにも活用できるみたいです。とっても便利な関数ですね~。これからもいろいろ試して、活用していきたいと思います!