プログラミングの勉強を初めて数ヶ月がたち、データベースの勉強もはじめました。
そんな中、データベースで〜以上〜以下の範囲を選択したくて「BETWEEN A AND B」や 「A >= C AND C <= B」 を利用したのですがなぜか以上以下ではなく以上未満のようになってしまいはまったことについて書いていきたいと思います。
料金で比較した時は無事使えていたのに不思議です。
以上未満なので未満の部分の数値を1つ上げれば以下になるしそう使うのかなとも思ったのですがそれではなんかおかしいし、勉強にならないので原因を追求してみることにしました。
状況
わかる人には「あ〜そういうことね」と思われると思いますが、私はデータベースに登録した時間(Timestamp)を元に何日から何日までのデータを取得しようとしていました。
以上未満になってしまったコード例1
SELECT RECORD_DATE FROM データベース名 WHERE RECORD_DATE BETWEEN ‘20190610’ AND ‘20190615’
「データベースのレコードデートの20190610と20190615の間でレコードデートを取得して」とSQLに指示したつもりでした。初めのうちは未満になっているかも気づかず以下が正常かと思っていました。
しかし20190615のレコードデートは取得されていないことに気づいて、BETWEEN A AND Bなんてこじゃれたコードの書き方をしたからいけないのかとシンプルに下記コードに書き換えてみました。
以上未満になってしまったコード例2
SELECT RECORD_DATE FROM データベース名 WHERE RECORD_DATE >= ‘20190610’ AND RECORD_DATE <= ‘20190615’
「データベースのレコードデートが20190610以上(>=)かつレコードデートが20190615以下(<=)のレコードデートを取得して」と指示したはずですがこちらも同じように20190615が取得されていませんでした。
その後は以上は効くのに以下が効かないってどういうこと?
と書き方が間違っているのか、一文字ずつ検証してみたり、日付の書き方がおかしいのかなと2016/06/15と書いてみたりしてみましたが解決には至りませんでした。
解決編
そこからいろいろ探してみた結果、この場合だと「時間分秒」が抜けているため2016/06/15日の0時0分00秒までで比較していることがわかりました。そのため2016/06/15日の10時に登録されたデータはデータベースから取得されなかったようです。
これなら以上の部分は正常に動いていることに納得です。未満だと思っていたけれど一応以下で機能していたんですね。
ということは20190615235959と書くのか?とおもいました。
一応解決コード
SELECT RECORD_DATE FROM データベース名 WHERE ‘20190610’ <= RECORD_DATE AND RECORD_DATE <= ‘2019060615235959’
実際にそのようにかくと私の思う以上以下の条件を満たすことができました。
それでもなんだかかっこよくないし、ともやもやしていると個人的に初めて見る書き方がされているサイトをみつけました。
参考になったサイト:How do I correctly compare dates using to_char?
解決コード
SELECT TO_CHAR(RECORD_DATE,’YYYY.MM.DD’) FROM データベース名
WHERE TO_CHAR(RECORD_DATE,’YYYYMMDD’) >= ‘20190610’ AND TO_CHAR(RECORD_DATE,’YYYYMMDD’) <= ‘20190615’
他にも書き方があるのかもしれませんがひとまず納得できる解決方法を見つけられて満足です。
TO_CHARで日付時間のデータを保持していたRECORD_DATEを文字データ西暦月日に変換してくれているようです。時間分秒が切り離されて20190615以下になったようです。
わかってしまえば無知ゆえにはまっただけでした。思ったより短い記述にならなくてちょっと面倒に感じましたが新しいことを覚えられてよかったです。