(PHP・POSTGRESQL)特定期間内に誕生日を迎えるユーザを抽出したい


例として下記のようなレコードがDBにあるとします

名前 | 誕生日
-----------------
a | 19901016
b | 19930312
c | 19600106
d | 19800110

※誕生日は本来タイムスタンプで格納されていますが
わかりやすくするためにYYYYMMDD形式で表記しています

上記テーブルから1月6日から1月10日の間に誕生日を
迎える人を抽出するにはどのような方法がベストでしょうか
注意していただきたい点としては誕生日の年は考慮せずに
純粋に月と日のみの範囲で抽出したいという点になります
(上記テーブルで考えるとcとdの2件を抽出したい)

よろしくお願いします

回答の条件
  • 1人2回まで
  • 登録:2009/04/20 13:48:45
  • 終了:2009/04/27 13:50:02

回答(3件)

id:kn1967 No.1

kn1967回答回数2915ベストアンサー獲得回数3012009/04/20 14:53:25

ポイント26pt

シンプルに・・・

SELECT * FROM テーブル WHERE to_char(誕生日, 'MMDD') BETWEEN '0106' AND '0110';
id:jayz

いつもありがとうございます

期待通りの値を得ることができました

・・・と思いましたが

年をまたいで範囲を指定する場合に一工夫必要ですね

2009/04/21 11:49:16
id:chuken_kenkou No.2

chuken_kenkou回答回数722ベストアンサー獲得回数542009/04/20 14:41:34

ポイント27pt

timestamp型から日時を得るには、date_part等の

http://www.postgresql.jp/document/pg820doc/html/functions-dateti...

があるのですが、ここでは一つの関数で月日を得られるto_char関数

http://www.postgresql.jp/document/pg820doc/html/functions-format...

を使った例です。

select
  *
 from t1
 where to_char(birthday,'MM-DD') between '01-06' and '01-10'

もし母体件数が多く、インデクスを利用しないと性能が出せないようであれば、PostgeSQLには商用RDBMSで多く実装されている  を定義するといった手段があります。

id:chuken_kenkou No.3

chuken_kenkou回答回数722ベストアンサー獲得回数542009/04/20 14:48:03

ポイント27pt

#1です。

式インデクスの説明が漏れていました。

PostgreSQLでは、商用RDBMSで多く実装されている式に対するインデクスを定義できます。

http://www.postgresql.jp/document/pg820doc/html/indexes-expressi...


定義形式は、(式)と、式を括弧で囲むのが特徴です。

create index インデクス名 on 表名((式));

#1の検索条件でも有効利用可能なインデクスを定義する例です。

create index t1ix1 on t1((to_char(birthday,'MM-DD')));
id:jayz

式に対してもインデックスが定義できることを知りませんでした

参考になります

2009/04/21 12:45:24
  • id:kn1967
    >年をまたぐ

    SELECT * FROM temp
    WHERE (to_char(birthday, 'MMDD') BETWEEN '0101' AND '0106')
    OR (to_char(birthday, 'MMDD') BETWEEN '1016' AND '1231');
    といった具合です。
    ユーザーインターフェースのほうで適宜SQLを使い分けると良いでしょう。

    ユーザー定義関数を作成しておいて「年をまたがない場合」
    「年をまたぐ場合」の2つの式を使い分けさせるという手もありますが
    環境によっては動かない場合もありますし、動作速度的にも微妙です。

    また、式インデックスという話も出てますが、こちらの選択も微妙です。
    速度重視の場合は年月だけのカラムを用意するほうが賢い選択となるかもしれません。
  • id:kn1967
    別案。
    SELECT * FROM temp
    WHERE NOT (to_char(birthday, 'MMDD') BETWEEN '0107' AND '1015');

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません