tetu式

ゲームと音楽・作曲の自己満足と悩みどころの多いプログラムのブログ。

SQL:テーブルの日付型カラムにランダム日付でUPDATEする

応用が利きそうなので備忘録として。
使用言語はPostgreSQLです。
ランダム数値生成関数、キャスト関数、文字列結合子あたりを
置き換えれば他のSQL言語でも使えるかと。

SELECT i,
   to_date(round((random() * ('最大年数' - '最小年数'))::numeric, 0) + '最小年数' || '-' ||
   round((random() * (12 - 1))::numeric, 0) + 1 || '-' ||
   round((random() * (31 - 1))::numeric, 0) + 1, 'YYYY-MM-DD') as rnd_date
FROM GENERATE_SERIES(1, '生成行数') i;

上記のSQL
‘最大年数'→1990
'最小年数'→1920
'生成行数'→1000
として実行した場合、1920-01-01~1990-12-31のランダム日付レコードが
連番カラム付きで1000行分作成されます。

29~31日が存在しない月にその日付が振られた場合は超過分を判断して
正しい日付に直してくれます。(例:1955-02-31→1955-03-03)

PKが一種類かつ、数値(連番)型のテーブルに限定されますが、
UPDATEに利用することで日付型カラムにテストデータを付与できます。
まぁ、UPDATEするにあたって連番生成ではなくて単にPKを指定すればいいのですが。

-- 例:登録メンバーテーブルの誕生日をランダム日付で再付与
UPDATE regist_member SET
    birthday = r.rnd_date
FROM (SELECT i,
    to_date(round((random() * (1990 - 1920))::numeric, 0) + 1920 || '-' ||
    round((random() * (12 - 1))::numeric, 0) + 1 || '-' ||
    round((random() * (31 - 1))::numeric, 0) + 1, 'YYYY-MM-DD') as rnd_date
FROM GENERATE_SERIES(1, 1000) i) r
WHERE
    regist_member.id = r.i
-- 例:登録メンバーテーブルの誕生日をランダム日付で再付与(PK利用版)
UPDATE regist_member SET
    birthday = r.rnd_date
FROM (SELECT m.id,
    to_date(round((random() * (1990 - 1920))::numeric, 0) + 1920 || '-' ||
    round((random() * (12 - 1))::numeric, 0) + 1 || '-' ||
    round((random() * (31 - 1))::numeric, 0) + 1, 'YYYY-MM-DD') as rnd_date
FROM regist_member m) r
WHERE
    regist_member.id = r.id