• ベストアンサー

Firebirdで年齢算出

 現在Firebird1.5を使用していますが、SELECTする際にテーブルに登録されている生年月日(int型/yyyyMMdd形式)より年齢算出を行う方法が分からなくて困っています。  PostgreSQLであればage関数等を使用して年齢算出できますが、Firebirdではそのようなユーザー定義関数は用意されていないのでしょうか?  Firebird関連のHPや書籍で調べましたが、データベースにあまり詳しくない事もあり、手詰まりといった状況です。もし方法をご存知の方がおられましたら、お手数ですがご回答よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • neko1999
  • ベストアンサー率100% (1/1)
回答No.2

舌足らずだったのですが、EXTRACT関数は数値を返す関数ですので、日付が数値ならば直接比較できます。 日付がパックされた数値ならば、割り算や標準UDFのMODやFLOOR(少数切り捨て)を組合わせることにより、目的のものを抜き出せます。 また、日付が文字列にパックされているのなら、1.5で内部関数に昇格したSUBSTRで抜き出せます。 また、Firebirdならば特徴の1つである計算型の列を定義できますので、あらかじめ日付を分解する計算型の列を作っておくと、このような場合は便利かもしれません。 計算型の列は、記憶領域もメタデータ以外には消費しませんのでとても効率的です。 計算型の列に関しては、この前と同じですが貼り付けたURLにある、SQLリファレンスの、CREATE TABLEを見てください。 比較する日付のほうを加算と乗算することにより、月日だけを比較するSQLを書いてみました。20040901が日付をパックした数値です。 isqlなどで実行してみてください。ただし、MODを使っていますので、あらかじめ標準UDFを読み込んでおく必要があります。 SELECT CASE WHEN (EXTRACT(MONTH FROM CURRENT_DATE)*100+EXTRACT(DAY FROM CURRENT_DATE))>MOD(20040901,10000) THEN 'Before' ELSE 'Today or Later' END FROM rdb$database;

参考URL:
http://nekomimi.s41.xrea.com/x/firebird/pukiwiki/?FrontPage
ryvius
質問者

お礼

再度ご回答ありがとうございました。 MODやFLOORでYYYYMMDD形式のデータから年・月・日の取り出しが出来そうですね。 ご教授いただいたSQL文を元に、年齢算出のSQL文を作成してみます。 非常に助かりました。感謝×2です!

その他の回答 (1)

  • neko1999
  • ベストアンサー率100% (1/1)
回答No.1

年齢算出の関数はわたしは記憶にありません。 しかし、SELECTのCASEとEXTRACT,CURRENT_DATE関数により算出可能だと思われます。 FB1.5のSELECTに関しての日本語リファレンスがあるWikiを参考URLに書きましたので参考にして下さい。 ほかにもUDFやストアドプロシージャという手もあります。 簡単な例だと次のような感じのSQLになると思いますが、確認していませんので論理は間違っているかもしれません。注意して下さい。t.dはDATE型になっています。 あと、ここだとインデントが崩れるので見づらいです。 SELECT CASE WHEN EXTRACT(YEAR FROM t.d)>=EXTRACT(YEAR FROM CURRENT_DATE) THEN CASE WHEN EXTRACT(MONTH FROM t.d)<EXTRACT(MONTH FROM CURRENT_DATE) THEN EXTRACT(YEAR FROM CURRENT_DATE)-EXTRACT(YEAR FROM t.d) ELSE CASE WHEN EXTRACT(DAY FROM t.d)>EXTRACT(DAY FROM CURRENT_DATE) THEN (EXTRACT(YEAR FROM CURRENT_DATE)-EXTRACT(YEAR FROM t.d)-1) ELSE EXTRACT(YEAR FROM CURRENT_DATE)-EXTRACT(YEAR FROM t.d) END END ELSE -1 END FROM t;

参考URL:
http://nekomimi.s41.xrea.com/x/firebird/pukiwiki/?FrontPage
ryvius
質問者

お礼

非常に丁寧なご回答ありがとうございます。 CASEとEXTRACTで年・月・日ごとに調べていくというのは盲点でした。関数ばかりに目が行っていたもので… ご教授いただいたSQL文の改造でDATE型からの年齢算出は問題なさそうです。 インデントは崩れますが、同じ問題に直面される方がおられるかも知れませんので、こちらで作成したSQLを載せておきます。(※t.dateはDATE型) ----------------------------------------------- SELECT CASE WHEN EXTRACT(YEAR FROM t.date) <= EXTRACT(YEAR FROM CURRENT_DATE) THEN CASE WHEN EXTRACT(MONTH FROM t.date) < EXTRACT(MONTH FROM CURRENT_DATE) THEN EXTRACT(YEAR FROM CURRENT_DATE) - EXTRACT(YEAR FROM t.date) ELSE CASE WHEN EXTRACT(MONTH FROM t.date) = EXTRACT(MONTH FROM CURRENT_DATE) THEN CASE WHEN EXTRACT(DAY FROM t.date) > EXTRACT(DAY FROM CURRENT_DATE) THEN EXTRACT(YEAR FROM CURRENT_DATE) - EXTRACT(YEAR FROM t.date) - 1 ELSE EXTRACT(YEAR FROM CURRENT_DATE) - EXTRACT(YEAR FROM t.date) END ELSE EXTRACT(YEAR FROM CURRENT_DATE) - EXTRACT(YEAR FROM t.date) - 1 END END ELSE -1 END FROM testTable t; ----------------------------------------------- あとは生年月日(int型/yyyyMMdd形式)をDATE型に変換できればいけそうですが、FirebirdってTO_DATE関数って無いんですね。CAST関数だとYYYYMMDD形式からの変換は無理のようですし… どなたかYYYYMMDD形式からDATE型への変換方法をご存知の方がおられましたら、お手数ですがご教授お願いいたします。

関連するQ&A