新元号へのデータ置換(SQL)

  • このエントリーをはてなブックマークに追加

プロジェクトの改修で「新元号への対応」があり、一番苦労した「DBに2019年5月1日以降の日付が存在した場合に、平成を新元号に置換する」SQLを、備忘録代わりに残します。

【環境】

postgresql9.5

【DBの設定】

今回テーブルのカラムについては3つ、西暦、和暦(例:平成~年)、和暦略記(例:H.~年)を用意。1つ年月日を入力し登録したら3パターンで格納することを想定します。
カラムについては下記の通り設定する。

テーブル名:datesample

論理名 物理名 データ型
西暦 seireki date
和暦 wareki character varying(10)
和暦略記 wareki_ryaku character varying(22)

更にサンプルとして下記のレコードを登録

カラム名 seireki wareki wareki_ryaku
レコード1 2019-07-01 平成31年7月1日 H.31.7.1
レコード2 2021-01-01 平成33年1月1日 H.33.1.1

この2つのレコードを今回置換することにします。

【コードを書く前に注意点】

置換にあたり、注意事項があります

・今回の置換は、西暦から和暦を計算し置換を行う
和暦を分解し、計算・元号変換して置換する方法もできないことはないですが、月・日が1桁の場合と2桁の場合があり、それぞれに対応するとコードが複雑になるので、西暦を基に計算する方が確実かつ短く書けます。

・カラムのデータ型に注意
今回はサンプルでテーブルを作成し汎用的なカラムの設定を行いましたが、実際のプロジェクトのDBでは例外的な設定もあります(私はこれで引っかかりました…)。例えば西暦は本来date型で設定していることが多いのですが、稀に文字列型で設定している場合があります。状況としてありえるのが、年月日を入れるパターンと年月を入れるパターンがあるからdate型にできない、といった場合。この場合は今回書くコードを修正して頂く必要があるので気をつけて下さい。

【やってみましょう】

では早速コードを見てみましょう。
ちなみに今回は、新元号が分からないので、仮に’元号’、’G’としております。

UPDATE
  datesample
SET
  wareki =
CASE
  WHEN seireki >= '2019/05/01 00:00:00' THEN '元号' || TO_CHAR(TO_NUMBER(TO_CHAR(seireki, 'YYYY'), '9999') - 2018, 'FM99') || TO_CHAR(seireki, '年FMMM月FMDD日')
  ELSE wareki
END,
  wareki_ryaku =
CASE
  WHEN seireki >= '2019/05/01 00:00:00' THEN 'G.' || TO_CHAR(TO_NUMBER(TO_CHAR(seireki, 'YYYY'), '9999') - 2018, 'FM99') || TO_CHAR(seireki, '.FMMM.FMDD')
  ELSE wareki_ryaku
END,
  wareki = REPLACE(seireki, '元号1年', '元号元年');

結果は以下の通りになります。

カラム名 seireki wareki wareki_ryaku
レコード1 2019-07-01 元号元年7月1日 G.1.7.1
レコード2 2021-01-01 元号3年1月1日 G.3.1.1

処理は2つ。
①まず西暦を利用し、和暦、和暦略記を作成。
②その後和暦に関しては、新元号「1年」の場合は「元年」にする必要があるので変換する。

1つ目の処理が少しややこしいので解説します。
まずTO_CHARで西暦から年だけを抜き取り、計算できるようにTO_NUMBERで整数型に変換します。抜き取った年から2018年を引き、新元号と結合。更に、TO_CHARで西暦から月と日を抜き取り年~月~日を結合します年月日を抜き取る際に’FM’と入れているのは空白を入れないためです。
また、date型に関しては、DBには’2019-07-01’としか表示されておりませんが、実際には’2019-07-01 00:00:00’という形で入っております。date型を比較する際は気をつけましょう。
ELSEについては、条件に該当しなかった場合に元のデータに戻す処理になるのですが、これがなかったら条件に該当しないものはnullになりますので注意が必要です。

【まとめ】

他にも方法はありそうでしたが、個人的にはこのコードが一番シンプルだと思いました。元号を切り替える作業はそうそう無いので、凄く勉強になりました。DBの置換は少しでも間違えると大変なことになるので、ぜひ覚えておきたい。

  • このエントリーをはてなブックマークに追加