[pgsql-jp: 26297] Re: 記念日等の範囲検索
Takao Kato
sirius @ jp.fujitsu.com
2002年 6月 6日 (木) 10:18:44 JST
加藤@川崎です。
> 条件絞り込みで
> a月b日($s_day)〜c月d日($e_day)の該当者を検索をするとした場合
> select * from user where memorial_day <= '$e_day' and memorial_day
> >='$s_day'
>
> むりやり年をつけたして検索もできそうなかんじもしたのですが、年をまたぐ指
> 定の場合(例えば12/20〜1/10までを検索)などどうすればいいのかと。
朝の頭の体操と言うことで、少し考えてみました。手段として、
(1)時期を「月」単位で切ってしまう
(2)条件判定時にmemorial_dayに年を加えてしまう
(3)memorial_dayに年情報を加える
の3つの方法が「ぱっ」と思いつきます。
(1)時期を「月」単位で切ってしまう
これは「月」で一度振るいにかけてしまうことで、12/20〜1/10なんて面倒
臭い判定を避ける方法です。これは当然思いついていると思います。
これに条件をもう一つ加えて、月を跨ぐ場合には上記条件を二回にわけて
しまう、、、例えば 12/20〜12/31と1/1〜1/10
クエリをどこから喰わせるのかで $e_day と $s_day の値を算出する方法
が変わって来ますが、仮に分離した結果判定範囲が
$s_day〜$e1_day
$s2_day〜$e_day
としたら
select * from user where
memorial_day between $s_day and $e1_day or
memorial_day between $s1_day and $e_day;
で良いですよね。(overlapsでもOK)
(2)条件決定時にmemorial_dayに年を加えてしまう
memorial_dayに今年と来年の「年」情報を条件判定時に加えてしまうもの
です。ただ「年」情報をどう加えれば良いかは別の方にお願いするとして、 ^^;;
年情報を加えたフィールドとして memorial_now memorial_next とでもし
て($s_dayと$e_dayにも年情報が加わっている)
select * from user where
memorial_now between $s_day and $e_day or
memorial_next between $s_day and $e_day;
でいけると思います。(overlapsでもOK)
(3)memorial_dayに年情報を加える
(2)とは memorial_dayの型を初めから date 型(timestamp)にしておくとこ
ろが異なります。くわえて、cronなどで日に1度(例えば0時に)現在よりも
古い日の年情報を更新してしまいます。こうすれば(1)や(2)のように小細
工しなくても($s_day/$e_dayともにdateかtimestamp型なら)
select * from user where
memorial_day between $s_day and $e_day;
で終わりですよね。
注意点としては、「誕生日」は更新しても「生年月日」は更新してはいけ
ない、、、そりゃそうですよね。誕生日は毎年やってきますが、生年月日
は一生で一度ですから。このようにカラムの入力値に依存する関係を忘れ
て無闇に更新するとDBの意味がなくなったりします。
聡明な皆さんはともかく、僕なんかは忘れてやってしまいそうです ^^;
こんなところかなぁ? ちなみにクエリ生成をPHPやPerlでやるならゴリゴリで
きます。が、SQLだけでもっとシンプルかつ聡明な方法ありましたら教えてく
ださい。^^
----
加藤@川崎
お便りは kato @ lantc.cs.fujitsu.co.jp まで
pgsql-jp メーリングリストの案内