アプリ版:「スタンプのみでお礼する」機能のリリースについて

 現在Firebird1.5を使用していますが、SELECTする際にテーブルに登録されている生年月日(int型/yyyyMMdd形式)より年齢算出を行う方法が分からなくて困っています。
 PostgreSQLであればage関数等を使用して年齢算出できますが、Firebirdではそのようなユーザー定義関数は用意されていないのでしょうか?

 Firebird関連のHPや書籍で調べましたが、データベースにあまり詳しくない事もあり、手詰まりといった状況です。もし方法をご存知の方がおられましたら、お手数ですがご回答よろしくお願いします。

A 回答 (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 …
    • good
    • 0
この回答へのお礼

再度ご回答ありがとうございました。

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

お礼日時:2004/09/01 13:27

年齢算出の関数はわたしは記憶にありません。


しかし、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 …
    • good
    • 0
この回答へのお礼

非常に丁寧なご回答ありがとうございます。
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型への変換方法をご存知の方がおられましたら、お手数ですがご教授お願いいたします。

お礼日時:2004/08/31 22:32

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す