ほんじゃーねっと

おっさんがやせたがったり食べたがったりする日常エッセイ

PostgreSQLでテスト用組み合わせパターンデータを一括生成する

f:id:piro_suke:20161110013537j:plain

先日書いたgenerate_series関数を使用したテストデータ生成の続き。

blog.honjala.net

どうせテストデータを作成するなら、

連番だけでなく、必要なパターンの組み合わせデータを生成したい。

ちょっと前にPythonやClojureを使った組み合わせデータ作成のスクリプトを

作成した時は専用のライブラリを使用したのだけど、

blog.honjala.net

PostgreSQLのgenerate_series関数とjoinを組み合わせたら

ぐっと簡単に実現できた。

サンプル

まずはシンプルに値の組み合わせデータを作成してみる。

select
    x   
    ,y  
    ,z  
from
    generate_series(1, 3) as x
    ,generate_series(0, 1) as y
    ,generate_series(1, 2) as z
;

結果はこうなる。

 x | y | z 
---+---+---
 1 | 0 | 1
 1 | 1 | 1
 2 | 0 | 1
 2 | 1 | 1
 3 | 0 | 1
 3 | 1 | 1
 1 | 0 | 2
 1 | 1 | 2
 2 | 0 | 2
 2 | 1 | 2
 3 | 0 | 2
 3 | 1 | 2
(12 行)

簡単。

これをinsert-selectにすれば組み合わせテストデータを生成できる。

generate_seriesの結果をcase文で変換したり、

row_number()を使って行番号を出力するようにすればさらに

柔軟にデータを作成できる。

select
    row_number() over()                                                                                                                                                                
    ,x
    ,case when y = 0 then                                                                                                                                                              
        '有効'
    else
        '無効'
    end as y
    ,case when z = 1 then
        '男性'
    else
        '女性'
    end as z
from
    generate_series(1, 3) as x
    ,generate_series(0, 1) as y
    ,generate_series(1, 2) as z
;

結果

 row_number | x |  y   |  z   
------------+---+------+------
          1 | 1 | 有効 | 男性
          2 | 1 | 無効 | 男性
          3 | 2 | 有効 | 男性
          4 | 2 | 無効 | 男性
          5 | 3 | 有効 | 男性
          6 | 3 | 無効 | 男性
          7 | 1 | 有効 | 女性
          8 | 1 | 無効 | 女性
          9 | 2 | 有効 | 女性
         10 | 2 | 無効 | 女性
         11 | 3 | 有効 | 女性
         12 | 3 | 無効 | 女性
(12 行)

関連マスタがあるならそれもjoinすれば

関連マスタのデータ分の組み合わせデータができる。

下記の例ではproduct_test_categoriesという関連マスタと

joinして組み合わせデータを作成してる。

select
    row_number() over()
    ,x  
    ,case when y = 0 then
        '有効'
    else
        '無効'
    end as y
    ,case when z = 1 then
        '男性'
    else
        '女性'
    end as z
    ,cat.name as cat_name
from
    generate_series(1, 3) as x
    ,generate_series(0, 1) as y
    ,generate_series(1, 2) as z
    ,product_test_categories cat 
;

おわり

プログラムを作るより大分簡単だった。

もしかしてみんなこうやってテストデータを作成してるんだろうか。

プログラマのためのSQL 第4版 すべてを知り尽くしたいあなたに

プログラマのためのSQL 第4版 すべてを知り尽くしたいあなたに