• ベストアンサー

日またぎの計算

こんにちはー 日またぎの計算についてアドバイスを頂きたく参上しました 通常、深夜12時で日付が変更するところを、深夜3時とか朝の7時とかに 日付が変わるような考え方の処理を作りたいのですが、どういう流れで 作ればよいのかわからないのでアドバイスが欲しいのです ※ たとえば 深夜3時に日付が変わるように定義したとすると 10/31 2:59:59までは10/30として処理する ということです 最終的に何をしたいのかと言いますと… DB(MYSQL 5.0.45)に、Aは ○時から○時まで という感じで格納された データがたくさんありまして、○時から○時の中に現在時刻が含まれる データのみを抽出したいのですが… 19時から23時 とかはいいんですが、22時から03時 とかになると日付が 変わってしまうので、比較がうまく出来なくて処理出来ないんです (データなし ということで 何も表示されません) ※DBのデータは始まりの時間が「19」みたいな感じで入っているので タイムスタンプとかは使えないのかなーと思ってます(そんなことないですかね??) とりあえず24時間の通念の、「深夜12時に日付が変わる」というところを 再定義 出来れば比較もうまくいくかなーと思って質問にきてみました そういう処理なら、他にもこういう考え方でも作れるよーみたいな アドバイスでも全然構いませんので、思いつくことがありましたら 教えて下さい(考え方だけわかれば後は自分で調べますので!!)

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

  • ベストアンサー
  • mitoneko
  • ベストアンサー率58% (469/798)
回答No.4

>データが入っている状態でフィールドのデータ型を変更するっていうのは なかなか危険な行為なんでしょうか?  あっさりと返事してしまいますが、非常に危険な行為です。  うまくいくことも多々ありますが、データベース内のデータの保護だけを考えただけでも、最低、データ変換の詳細な規則は確認しておくべきです。  また、すでにデータベースがあると言うことは当然、そのデータを扱っているアプリケーションがすでに存在すると言うことです。当然そのアプリは元のデータ型を期待してプログラミングされていますから、その修正が必要です。  さて、もし、データ型を変更しようという気合いがあるのであれば、別法をひとつ。  まず、ビューを一つ作ります。  ビューの基本型は、  create view sansyouyou select fl1, fl2, fl3, fl4 ・・・・ from motonohyou  と基本は、元の表とおなじものです。  ただし、このビューのデータ型がちゃんと日付型になるように、ビューを作成するselect文の該当フィールドだけは、型変換をかけてください。必要であれば、ユーザー関数を使用して数値の整合性も維持できるように作成します。  これなら、他の人に迷惑はかけずに、自分は自分の都合の良い形式で今後プログラムをすることはできます。  ただ・・・・悲しいかな。インデックスなどのパフォーマンスの改善には手が出せないのが欠点です。また、わずかとはいえ、ビューそのものの扱いでパフォーマンスが低下します。  よって、一時しのぎと解釈してください。本来なら、テーブルを新規で作り、元のテーブルからデータをすべてインポート(insertの基礎をselect文で書ければ一発です。)するのがベストなのでしょうが。それをするにも、先の一時しのぎのビューは作業を簡単にする手助けになります。ただし、当然ですが、既存のアプリを新しい表を参照するように全部作り替える必要があります。  というわけで、教訓は、テーブルの設定は慎重の上にも慎重に・・・後でやるのはとっても大変です。というにつきます。

koke29
質問者

お礼

mitoneko様 あっさり回答ありがとうございます~ 予想通り危険な行為ということですねー 先走ってやらなくて良かったです ビューというのは初めて聞く言葉なので、よく調べてみて 私にも扱えそうなものなら利用してみようと思います 参照させるテーブルについては、もともと設定ファイルから読み込んだ 変数で扱っているので、テーブル名が違うものになっても設定ファイルの 書き換えのみで対応出来そうです(ご忠告の内容はこれのことですよね?) 教訓も重々身に染みました 社内で利用する簡単なアプリのために、素人同然の私のような人間が 独学で作り上げたものなので、ホント穴だらけなんですよね… これを踏み台にして、これからも勉強していきますね たぶんまた、ナゾの質問を書き込みに来ると思うので良かったら その時にもアドバイスお願いしますー

その他の回答 (3)

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.3

おそらくDBの設計がわるいですね 最初から検索条件がきまっているのであれば、それに有効な フィールドを用意すべきでしょう。 インデックスが聞かない場合はSQLの効果は半減しかねないので

koke29
質問者

お礼

yambejp様 いつもありがとうございます 皆様のご指摘と同じく、DBの設計なんですね 今回のは本当、それに尽きますね… データが入っている状態でフィールドのデータ型を変更するっていうのは なかなか危険な行為なんでしょうか?まだやったことないんです ちなみに今のデータ型って見たらenumになってました 入力時にselectさせるからということでenumにしたっぽいんですけど DB側から値を引っ張るわけじゃないんだから意味ないですよねぇ… とりあえずこのデータを複数の箇所で抽出条件にするということはなく 質問に記載した「やりたいこと」が出来ればそれ以上はないので もう少しPHP側の処理を考えてみることにします… (データ型の変更が比較的難しくないことなら、それも考慮します) と、いうことで DBの設計は置いておいて 何かいい知恵がありましたら…アドバイス頂けると助かります

  • mpx
  • ベストアンサー率71% (149/209)
回答No.2

DBでの時間記録のフィールドの形式によっては変更が必要ですが TIME形式の場合は、クエリーのWHERE句を下記のようにすれば 一発で検索できるのでは?  開始時刻を stime  終了時刻を etime  現在時刻を仮に 00:06:22 とします。 WHERE ((stime <= etime) AND (stime <= '00:06:22') AND ('00:06:22' <= etime)) OR ((stime > etime) AND ((stime <= '00:06:22') OR ('00:06:22' <= etime)))

koke29
質問者

お礼

mpx様 アドバイスありがとうございます データ型見直したら enumになってました… テーブルの用意は私以外のものがやったのと、私もデータ型のことなど 全然わからない状態だったので何の疑問も抱かずに進めてしまいました 今回教えて頂いたWHERE句の書き方、いつか違う形で使うかもしれないので 覚えておきますね!ありがとうございました!!!

  • mitoneko
  • ベストアンサー率58% (469/798)
回答No.1

 では、考え方だけ。  おそらく、データベースに格納する時間データは、標準通りの日付規則で格納するのが扱いやすいかなと思います。(つまり、ちゃんと00:00で次の日になる。)  そうすれば、別段日またぎになろうが、何であろうが普通に、current_timestamp() between *** and *** で目的のデータは抽出できます。  こうしてしまう利点は、他の日付計算などでも、なんら特殊用件を考えなくてすむことです。特に、標準関数はすべて、0:00で日付が変わることを前提に作られていますから、これらの便利な関数を捨ててしまうのももったいないです。  さて、こうするとデータの格納と表示の際に、当然処理が必要です。格納の際には、もし、0:00から3:00までの時間であれば、日付を1日足してあげる。表示の際には、逆で日付から1日引いてあげるわけですね。  これは、ちょっとしたデメリットです。  どっちの手間が大きいか・・・・私は、標準日付関数を全部捨てる方が被害が大きいと思いますけど・・・。

koke29
質問者

お礼

mitoneko様 アドバイスありがとうございます DBの扱い方がすでに問題ということなんですね… データ型についてあんまりよくわからない状態で作ってしまったもので データの流用性など、考えないものになってしまったんですねぇ 日付の関数使えば時間の比較は楽ですもんね… とりあえず私の一存ではいまさらデータ型の変更も難しいので 今の状態でどうにか出来ないものか、もう少し考えてみます ご指摘ありがとうございました!!!

関連するQ&A