- ベストアンサー
betweenを使うyyyy/mm/ddでの範囲検索
2007年1月1日 から 2008年5月5日のデータがほしいのですが、どのような書き方をすればいいのか思いつきません。 年、月をまたがなければbetweenで指定できるのはわかりました。 わからない点は年をまたぐ、もしくは月をまたぐ場合はまた1月から、1日からの検索をしなければならないというところです。 検索するにしても、どんな単語で検索をかければいいのかわかりません。 ヒント、もしくは検索で使うキーワードでよろしいのでよろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
#2です。 SQL99で規定され、MySQLでも実装されている行値構成子(または行値式)と呼ばれる構文を使えば簡単です。 where (年,月,日)>=(2007,1,1) and (年,月,日)<=(2008,5,5) #3さんの提示したようなSQLでも実現できますが、条件式で関数を使ったりして列を加工すると、MySQLの場合、インデクスが使われない場合が多いので、性能を重視する場合はEXPLAINで十分に確認してください。
その他の回答 (3)
- soramame99
- ベストアンサー率46% (12/26)
各カラムの値を使って、DATE型の値を作ってBETWEENで比較すれば良いと思いますよ。 SELECT * FROM table WHERE DATE(concat_ws('-',yyyy,mm,dd)) BETWEEN '2007-01-01' AND '2008-05-05';
お礼
お返事ありがとうございます。返信が遅れて申し訳ございません。 実行可能なサンプルまでいただいて感謝しております。 ありがとうございます!!
- chukenkenkou
- ベストアンサー率43% (833/1926)
日付が入っている列のデータ型は、date型ではないのですか? 年月日を、それぞれ別の列に格納しているのでしょうか?
補足
回答ありがとうございます。返信が遅れて申し訳ございません。 私の説明不足でした。 年_yyyyと月_mmと日_ddという3つのデータ型に分かれており、 3つともint型です。 そのため、年、月、日で3回betweenを使って検索したところ、 半端な結果しか得られなかったということです。 今考えている別の方法があるのですが、 今度はこういう形で検索してみたいと思います。 2007年1月1日から2008年5月5日までの範囲を検索したとします。 最初の2007年1月のデータをまずとりだす式を書きます。 それをORで2008年5月以外の2007年2月から2008年4月の間を検索する式と繋ぎ、 最後に2008年5月1日から5日までのデータを検索する式とまた ORでつなげればうまくいくかなぁと。 書いた式は select * from table where yyyy = 2007 && mm = 1 && dd between 1 and 31 or yyyy between 2007 and 2008 && mm between 1 and 12 && dd between 1 and 31 or yyyy = 2008 && mm = 5 && dd between 1 and 5; です。しかし、orで繋げた2つめの式で2008年の5月のデータがすべて読み込まれているので、 5日までではなく、31日まで表示されてしまいました。 う~ん、日付を3つのint型になんてわけなければよかったです。 もう間の値は年ごとに検索するしか方法はないのでしょうか? 説明がわかりづらくて申し訳ないです。 アドバイスよろしくお願いします。
- yambejp
- ベストアンサー率51% (3827/7415)
>年、月をまたがなければbetweenで指定できるのはわかりました。 情報元は?? 指定日 between '2007-01-01' AND '2008-05-05' でいけるでしょ?
補足
回答ありがとうございます。返事が遅れました。 年、月、日と3つのint型にわかれています。 >年、月をまたがなければbetweenで指定できるのはわかりました。 は、選択された範囲が2008年5月のみならば、1日から5日までの 検索はできるということです。誤解を招く書き方でした、申し訳ないです。 ANO.2の捕捉に改めて書いた式を記載させていただきましたので、 アドバイス等いただければありがたいです。 私の説明力不足で申し訳ありませんでした。 よろしくお願いします。
お礼
>MySQLの場合、インデクスが使われない場合が多いので、性能を重視する場合はEXPLAINで十分に確認してください。 そういう制限がやはりMYSQLでもあるんですね、よく確認してみます。 いろいろ考えてこのようなクエリを書いてみました。 where ((t_yyyy <= 2008 ) && ( t_yyyy <= 2008 && t_mm <= 5 ) && ( t_yyyy <= 2008 && t_mm <= 5 && t_dd <= 5 )) && (( t_yyyy >= 2007 ) && ( t_yyyy >= 2007 && t_mm >= 1 ) && ( t_yyyy >= 2007 && t_mm >= 1 && t_dd >= 1 )) やってることはchukenkenkou様のサンプルと同じだと思いますが、長い上にわかりづらいですね。 chukenkenkou様のサンプルを参考にもう一度どうすればよいのか よく考えてみます! ありがとうございました。