Menu

SQLで日付範囲抽出

2015年8月28日23:36  投稿者 : PINION

今回は、MySQLに登録日時などの日付時刻を記録しておいて、それをSQLで範囲指定して取り出す…といった場合の注意点について。

普通、日付時刻を記録するカラムを作っておいて(仮に「contents」というテーブルの「stamp」というカラムとする)

SELECT * FROM contents WHERE stamp BETWEEN '2015-01-01' AND '2015-12-31'

という形で BETWEEN を使って範囲指定をする訳ですが、DATE型のデータに対してならこれで構わないのですが、DATETIME型を使用している場合には、これでは正確な結果は得られません。

DATETIME型に対して、上の形式でSQLを発行すると、

SELECT * FROM contents WHERE stamp BETWEEN '2015-01-01 00:00:00' AND '2015-12-31 00:00:00'

としたのと同じになるからです。
つまり、「2015年12月31日になった瞬間」までのデータしか得られません。

以前、仕事で取引先のサイトに構築されたシステムと、こちらのサイトで構築したシステムを連動してデータをやり取りする…という事をやっていました。
こちらはサイトで法人向けにサービスを提供しているのですが、取引先のサイトで個人向けに同じような事をやりたいという事になり、ネームバリュー的にも取引先のほうが大きいのと、個人一人ひとりに請求しなくても取引先が一括で払ってくれるという事もあり、こちらも旨味があるという事で話が進められました。

ただ、処理のアルゴリズムを公開したくないという事で、相手のサイトでユーザーが入力したものを、こちらのサイトで構築したシステムに受け渡し、リアルタイムで処理をして結果を返して、返した結果を相手のサイトで生成して表示するという方式になり(個人的には、複数のサーバー間でのリアルタイムの受け渡しは、どちらかに障害が出た場合にデータの不整合が起きるので、気が進まなかったのですが)、いざ運用開始したら、一か月の利用数がこちらでカウントしたものと、相手先でカウントしたものであわないという事態が発生。

正直、開発時の打ち合わせ以外の取引相手とのやり取りは営業担当者がやっていたので、イマイチ状況が把握できなかったのですが、毎回ウチで出した数字のほうが、相手が出してくる数字より多いという、まるでウチが余分に請求してるみたいな感じで嫌な思いをしたのですが、ある時ピンと来ました。

それは、「合わない数」が「締日当日の利用者数」であるという事。
つまり、相手が出してくる数字は、締日当日の利用者数が含まれていないのではないか?と。
双方でデータベースに記録していて、締日までの利用数を検索していたのだとしたら、相手が上記のような「DATETIME型で記録しながら、日付しか指定せずに抽出」してしまうと、締日の利用数が入らないのは当然でしょう。

そんな訳で、「DATETIME型」で記録しているのであれば、データを抽出する場合は

SELECT * FROM contents WHERE stamp BETWEEN '2015-01-01 00:00:00' AND '2015-12-31 23:59:59'

と、最終日いっぱいまで指定してやりましょう。

コメントを残す

メールアドレスが公開されることはありません。

コメントフィード

トラックバックURL : http://www.mp-create.com/21.html/trackback

PHP & MySQLトップ