お知らせ
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 行)
いかがでしたでしょうか。
もっと応用すれば、テストデータを生成することにも活用できるみたいです。とっても便利な関数ですね~。これからもいろいろ試して、活用していきたいと思います!