SSブログ

クエリ 日付時刻フィールドの条件について [クエリ]

 日付時刻型のフィールドに対して条件を設定する場合の注意事項です。

 日付時刻型フィールドは、日付と時刻を一緒に格納できますが、日付のみを格納したり、時刻のみを格納する場合などもあります。
 格納されている内容により、条件抽出が思ったようにできない場合がありますので、いろいろな場合の抽出パターンを例に示します。


 このデータに対して、条件抽出を行います。

・日付と時刻が格納された項目の抽出

 基本的なパターン。日付と時刻が格納されている項目を抽出する場合は、日付と日時の両方を指定します。
 SQLのWHEREだと、
WHERE T日時.日付 = #2014/1/12 12:34:56#
 となります。

 日付時刻型の値を記述するときは、「#」でくくります。
 文字列の場合の「"」(ダブルクォーテーション)のようなものです。


 結果。
 同じ日付時刻のレコードが抽出されました。

 日付時刻が格納されている項目に対しては、日付と時刻が一致しないと抽出されません。
 日付のみを指定した場合や、
WHERE T日時.日付 = #2014/1/12#
 時刻のみを指定した場合は、
WHERE T日時.日付 = #12:34:56#
 抽出されません。

・日付のみが格納された項目の抽出

 日付のみの場合は、条件も日付のみを指定します。
 SQLだと、
WHERE T日時.日付 = #2014/01/13#
 と、なります。

 結果。

 日付に加えて、日時を付けてしまうと、
WHERE T日時.日付=#2014/01/13 12:00:00#
 抽出されません。

 ただし、日付のみが格納されている場合、内部的に時刻は「00:00:00」となっているので、
WHERE T日時.日付=#2014/01/13 00:00:00#
 の場合は、抽出できます。

・時刻のみが格納された項目の抽出

 時刻のみが格納されている場合は、条件も時刻のみを指定します。
 SQLだと、
WHERE T日時.日付 = #15:12:45#
 と、なります。

 結果。

 日付を付けてしまうと、
WHERE T日時.日付 = #2014/1/2 15:12:45#
 抽出されなくなります。

 時刻のみの場合も、日付部分は内部的に「1899/12/30」となっているので、
WHERE T日時.日付 = #1899/12/30 15:12:45#
 の場合は、抽出されます。



・Betweenを使う場合
 Betweenを使い、範囲で条件抽出を行う場合も、時刻が含まれているかどうかで、結果が変わってきます。
 テストデータはこちら。

 時刻がないパターンと、日付と時刻があるパターンです。

 日付のみの「T日時A」テーブルに対して、条件
WHERE T日時A.日付 Between #2014/3/15# And #2014/3/17#
 で、抽出を行うと、

 2014/03/16から2014/03/17までのレコードが抽出されます。

 これと同じ条件式を使って「T日時B」に対して抽出を行うと、

 2014/03/17分のレコードが抽出できません。

Between #2014/3/15# And #2014/3/17#
 と言う条件式の記述は、時刻部分が省略されていて、省略せずに記述すると、
Between #2014/3/15 0:0:0# And #2014/3/17 0:0:0#
 と、なります。2014/03/17 0:0:1以降は、この条件の範囲外となり、抽出することができません。
 データに時刻が含まれている場合は、
Between #2014/3/15 0:0:0# And #2014/3/17 23:59:59#
 とする必要があります。
 (「2014/3/15 0:0:0」は省略して、「2014/3/15」としてもかまいません)

 以上のように、日付時刻型のフィールドがある場合は、時刻が含まれるかどうかで扱いが変わってきます。
 グループで開発を行う場合は、仕様をしっかり把握しておく必要があります。

 蛇足ですが、日付と時刻が格納されている項目を、「2014/3/15」で条件抽出する場合は、
WHERE T日時B.日付 Between #2014/3/15 0:0:0# And #2014/3/15 23:59:59#
 と言う条件式になります。
 たまにこれを、
WHERE Format(T日時B.日付,'yyyy/mm/dd') = '2014/03/15'
 と言う条件式を書く人がいます。
 上のBetweenより簡潔に書けるからだと思いますが、この条件式の場合、すべてのレコードに対して、Formatの処理が行われますので、Betweenよりパフォーマンスが悪いと言えます。

 ただ、日付と時刻が格納されている項目で、時刻のみを範囲で抽出したい場合、例えば、日付にかかわらず、13:00から18:00まで(厳密には17:59:59まで)のレコードを抽出する場合は、
WHERE TimeValue(T日時B.日付) between #13:00:00# and #17:59:59#
 と言うように、TimeValueで時刻のみを取り出してから、範囲抽出する必要があります。
 パフォーマンスに問題が出る場合は、別に時刻のみを格納する項目を設けるなどした方が良いと思います。 


nice!(4)  コメント(0)  トラックバック(0) 

nice! 4

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。
※URL(リンク)は記述できません。

トラックバック 0

トラックバックの受付は締め切りました

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。