2013年10月10日木曜日

Oracleで年齢算出

昨日のExcel年齢計算に引き続き、
今度はOracleで年齢計算をするSQLを書いてみることにします。

単純に年齢を算出する方法を数学的式で書いてみると・・・

現在の年-生まれた年+1=年齢

ですよね? ちゃんとわかってますよねww
(日本では生まれたときは0歳で、翌年に初めて1歳となるわけなんで・・・)

でもそんな単純なもんではありません。
誕生日を過ぎていないとと1つ年が若い状態です。

たとえば
2014/10/10現在で1973/10/11生まれの人は まだ39歳なわけなので

2014-1973+1≠40歳ではありません。
40代ではないです!まだ30代です。(`・ω・´)キリッ

なんでちゃんと誕生日も加味して計算をしないと怒られます。
特に妙齢の女性は激オコプンです。

ではどうするのか?

Excelの関数では日付差分を求めるDATEIFという関数がありましたが、
Oracleにはあいにく同じ関数はありません。

ただし、似た様な関数でMONTHS_BETWEENと言うものがあります。

使い方はこんな感じです。

MONTHS_BETWEEN(日付1,日付2)

日付1と日付2の差分月を表示します。

ではやってみましょう。


※ちなみに日付1のほうが未来日、日付2に過去日に書かないと結果がマイナスになるんで注意です。
 あと、今日の日付を表示させる関数はOracleだとSYSDATEを使用します。
 また、どのTABLEも使用しない場合はDUALというオラクル固有のディクショナリテーブルを使って表示しています。

 
そうすると差分月が479ヶ月と小数点以下アリになります。

479ヶ月って何年ヨ!計算してみます。
あ・・・もちろん1年=12ヶ月ってしってるよね。
なんで479/12をやってみます。

Windows標準電卓

Oracleさんを酷使


小数点以下は考えない(あと何日で40歳なんだ~なんていうことは気にしない!)ので
そうなると1973/10/11生まれの人は2014/10/10現在で39歳であることが判明しました。

ではきっかり整数だけ求めたい場合はどうするのか・・・

小学校3年生くらいでやった切り捨てということをします。
世の中四捨五入のほうが多いですが、切捨て・切り上げなんていう単語もあったことを思い出してください(笑)

では切り捨てってどうするのよ?!という実際の話です。

実はOracleにかかわらずSQLにはちゃんと用意されております!!
でも切り上げる関数はないの・・・捨てるか四捨五入しかないんだね・・・ショボン(´・ω・`)救済策はあるけどね

TRUNC:切り捨て
ROUND:四捨五入(まるめ)
MOD:端数の取得

数式関数でよく使うのはコレくらいでしょうか?

そのほかに高校数学でやったサインやタンジェントなんていう関数もありますが、
あまり使う機会はないですよね (苦笑)>お仕事で使ったことありますが・・・(泣)

では切り捨ての関数TRUNCをつかって同じように479÷12をOracleにやってもらいましょう。


素敵に出てきましたね。

では全部をまとめて実行してみましょう。

■実行SQL

SELECT
 TRUNC (MONTHS_BETWEEN (SYSDATE,TO_DATE('1973/10/11','YYYY/MM/DD')) /12)
FROM DUAL;

■Oracle君の答え



美しく出ましたww

ちなみに!

日付型のデータを取り扱いをする際に一番最初に気をつけないといけないことってナンだと思いますか?









わかんない?
>デナオシテコイコノヤロウ




うるう年ですよ。閏年。

Oracle君の日付計算&年齢計算の方式は日本のやり方に準じたものではないので
閏年の日の計算がことなるんで注意が必要です。
>日本だと02/29生まれの人は翌月の最初の日(=03/01)に年齢が増えるというのが法律で定められております。
  民法143条2項ただし書参照

たとえば2000/02/29生まれの人が2013/02/28に↑上でしめしたSQLで年齢を算出しようとすると

■SQL
SELECT
 TRUNC(MONTHS_BETWEEN (TO_DATE('2013/02/28','YYYY/MM/DD'),TO_DATE('2000/02/29','YYYY/MM/DD')) /12)
FROM
 DUAL;
■Oracle君の結果

となり、2013/02/28の段階ですでに13歳になってしまっているわけです。

なのでSQLを発行するプログラムで制御するもしくはSQLの中で制御する記述が必要となります。

1 件のコメント: