8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

年齢の計算

Posted at

自分って何歳だっけ?って事がたま~にあるので、
そんな時に使ってる、年齢を求めるSQLを記載します。

SELECT TRUNC(MONTHS_BETWEEN(SYSDATE, TO_DATE(生年月日, 'yyyymmdd')) / 12) FROM DUAL

しかし、この方法だと閏年生まれな人の年齢がズレてました。
(例)1996年2月29日生まれな人の年齢を表示します。

SELECT
  TRUNC(MONTHS_BETWEEN(TO_DATE('1997/02/27', 'yyyy/mm/dd'), TO_DATE('1996/02/29', 'yyyy/mm/dd')) / 12) AS "1997/02/27",
  TRUNC(MONTHS_BETWEEN(TO_DATE('1997/02/28', 'yyyy/mm/dd'), TO_DATE('1996/02/29', 'yyyy/mm/dd')) / 12) AS "1997/02/28",
  TRUNC(MONTHS_BETWEEN(TO_DATE('1997/03/01', 'yyyy/mm/dd'), TO_DATE('1996/02/29', 'yyyy/mm/dd')) / 12) AS "1997/03/01",
  TRUNC(MONTHS_BETWEEN(TO_DATE('2000/02/27', 'yyyy/mm/dd'), TO_DATE('1996/02/29', 'yyyy/mm/dd')) / 12) AS "2000/02/27",
  TRUNC(MONTHS_BETWEEN(TO_DATE('2000/02/28', 'yyyy/mm/dd'), TO_DATE('1996/02/29', 'yyyy/mm/dd')) / 12) AS "2000/02/28",
  TRUNC(MONTHS_BETWEEN(TO_DATE('2000/02/29', 'yyyy/mm/dd'), TO_DATE('1996/02/29', 'yyyy/mm/dd')) / 12) AS "2000/02/29",
  TRUNC(MONTHS_BETWEEN(TO_DATE('2000/03/01', 'yyyy/mm/dd'), TO_DATE('1996/02/29', 'yyyy/mm/dd')) / 12) AS "2000/03/01"
FROM DUAL
  • 実行結果
1997/02/27 1997/02/28 1997/03/01 2000/02/27 2000/02/28 2000/02/29 2000/03/01
0 1 1 3 3 4 4

1996年2月29日生まれな人は
1997年2月27日の時点では「0」で、1997年2月28日に「1」となりました。
しかし、2000年2月28日の時点では「3」で、2000年2月29日に「4」となっています。
1997年2月28日の時点では「0」になって欲しかったのですが、想定と違う結果になっていました。

想定通りに年齢を取得出来る方法が無いか調べてみたところ、下記のような記述でも年齢を取得できるようです。

SELECT TRUNC((TO_CHAR(SYSDATE, 'YYYYMMDD') - YYYYMMDD形式の生年月日) / 10000) FROM DUAL

このSQLを用いて、前述と同じ1996年2月29日生まれな人の年齢を表示させてみると

SELECT 
TRUNC((TO_CHAR(TO_DATE('1997/02/27', 'YYYY/MM/DD'), 'YYYYMMDD') - TO_CHAR(TO_DATE('1996/02/29', 'YYYY/MM/DD'), 'YYYYMMDD'))/10000) AS "1997/02/27",
TRUNC((TO_CHAR(TO_DATE('1997/02/28', 'YYYY/MM/DD'), 'YYYYMMDD') - TO_CHAR(TO_DATE('1996/02/29', 'YYYY/MM/DD'), 'YYYYMMDD'))/10000) AS "1997/02/28",
TRUNC((TO_CHAR(TO_DATE('1997/03/01', 'YYYY/MM/DD'), 'YYYYMMDD') - TO_CHAR(TO_DATE('1996/02/29', 'YYYY/MM/DD'), 'YYYYMMDD'))/10000) AS "1997/03/01",
TRUNC((TO_CHAR(TO_DATE('2000/02/27', 'YYYY/MM/DD'), 'YYYYMMDD') - TO_CHAR(TO_DATE('1996/02/29', 'YYYY/MM/DD'), 'YYYYMMDD'))/10000) AS "2000/02/27",
TRUNC((TO_CHAR(TO_DATE('2000/02/28', 'YYYY/MM/DD'), 'YYYYMMDD') - TO_CHAR(TO_DATE('1996/02/29', 'YYYY/MM/DD'), 'YYYYMMDD'))/10000) AS "2000/02/28",
TRUNC((TO_CHAR(TO_DATE('2000/02/29', 'YYYY/MM/DD'), 'YYYYMMDD') - TO_CHAR(TO_DATE('1996/02/29', 'YYYY/MM/DD'), 'YYYYMMDD'))/10000) AS "2000/02/29",
TRUNC((TO_CHAR(TO_DATE('2000/03/01', 'YYYY/MM/DD'), 'YYYYMMDD') - TO_CHAR(TO_DATE('1996/02/29', 'YYYY/MM/DD'), 'YYYYMMDD'))/10000) AS "2000/03/01"
FROM DUAL;
  • 実行結果
1997/02/27 1997/02/28 1997/03/01 2000/02/27 2000/02/28 2000/02/29 2000/03/01
0 0 1 3 3 4 4

1996年2月29日生まれな人は
1997年2月28日の時点では「0」で、1997年3月1日に「1」になりました。
2000年2月28日の時点では「3」で、2000年2月29日に「4」となり、望んでいた結果が返ってきました。

年月日を8桁の数字にして、差を求めてから10000で割って端数を切り捨てると、年数だけを取得できるようです。
年齢を算出する数式と証明を記載している記事があったので、参考に記載しておきます。

参考リンクの記事にも記載がありましたが、業務で使用する場合、用途に沿った方法で年齢を算出する必要があります。

  • 参考

生年月日から年齢を簡易計算するコード

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?