質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Q&A

解決済

4回答

9591閲覧

月日のみの範囲を指定したクエリ

Praline

総合スコア46

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

0グッド

0クリップ

投稿2017/05/11 16:03

###前提・実現したいこと
DATE型で日付が保存されているカラムを対象に、今日から数日の日付を含む要素のみ抽出するクエリを作成したい。

###発生している問題・エラーメッセージ
※日付を保存しているカラム名は"MMDD"でDATE型

SQL

1select * from A where DATE_FORMAT(MMDD, '%m%d') between DATE_FORMAT('2014-01-01', '%m%d') and DATE_FORMAT('2015-02-01', '%m%d')

上記コードの場合、特に問題なく抽出が可能なのですが

SQL

1select * from A where DATE_FORMAT(MMDD, '%m%d') between DATE_FORMAT('2014-12-01', '%m%d') and DATE_FORMAT('2015-02-01', '%m%d')

このように、12月~1月をまたぐような期間を指定した場合、返り値が0件となってしまいます。
この場合は12/01~02/01の日付を持つ要素だけ抽出したいです。

###補足情報(言語/FW/ツール等のバージョンなど)
MySQLにて作成しています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

月日(MMDD)の情報のみで判定しているため、1201 <= 対象の日付 < 0201 となり絶対に条件を満たさないようになってしまっています。年(yyyy)の情報も判定に使用すると解決すると思います。

投稿2017/05/11 16:11

wattaru

総合スコア76

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wattaru

2017/05/11 23:06

MMDDカラムはDate型なので年(yyyy)の情報も抽出できると思います。
guest

0

ベストアンサー

ユーザーの登録日や誕生日のみの情報が欲しく、登録年は考慮しない

今日基準から何日間、という判定

要するに、
「現在日から N日以内に誕生日を迎えるユーザーを抽出したい」
と言うことでしょうか?

であれば、例えば 30日以内に誕生日を迎えるユーザーを抽出する場合、以下のような SQL文で実現できます。

sql

1SELECT * 2FROM A 3WHERE MAKEDATE(YEAR(CURDATE()) , DAYOFYEAR(MMDD)) BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY) 4 OR MAKEDATE(YEAR(CURDATE()) + 1, DAYOFYEAR(MMDD)) BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY);

参考:
http://stackoverflow.com/questions/8812280/birthdays-dates-between-two-months

実行結果

sql

1mysql> CREATE TABLE A (MMDD DATE); 2Query OK, 0 rows affected (0.02 sec) 3 4mysql> INSERT INTO A VALUES ('2000-01-01'), ('1990-05-12'), ('2010-06-11'), ('1980-06-12'), ('2017-02-01'); 5Query OK, 5 rows affected (0.00 sec) 6Records: 5 Duplicates: 0 Warnings: 0 7 8mysql> SELECT * FROM A; 9+------------+ 10| MMDD | 11+------------+ 12| 2000-01-01 | 13| 1990-05-12 | 14| 2010-06-11 | 15| 1980-06-12 | 16| 2017-02-01 | 17+------------+ 185 rows in set (0.00 sec) 19 20mysql> SELECT * 21 -> FROM A 22 -> WHERE MAKEDATE(YEAR(CURDATE()) , DAYOFYEAR(MMDD)) BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY) 23 -> OR MAKEDATE(YEAR(CURDATE()) + 1, DAYOFYEAR(MMDD)) BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY); 24+------------+ 25| MMDD | 26+------------+ 27| 1990-05-12 | 28| 2010-06-11 | 29+------------+ 302 rows in set (0.00 sec) 31 32mysql> SELECT * 33 -> FROM A 34 -> WHERE MAKEDATE(YEAR(CURDATE()) , DAYOFYEAR(MMDD)) BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 250 DAY) 35 -> OR MAKEDATE(YEAR(CURDATE()) + 1, DAYOFYEAR(MMDD)) BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 250 DAY); 36+------------+ 37| MMDD | 38+------------+ 39| 2000-01-01 | 40| 1990-05-12 | 41| 2010-06-11 | 42| 1980-06-12 | 43+------------+ 444 rows in set (0.00 sec)

投稿2017/05/12 08:22

KiyoshiMotoki

総合スコア4791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

月日だけぬきださなくては行けない理由はなにかあるのでしょうか?
たとえば5/12から前後3日分(5/9-15)のデータを抽出するとして
去年も一昨年も場合によっては未来日も抽出する必要があるのでしょうか?

'2014-01-01'から'2015-02-01'が1年以上の期間をしていしても1/1-2/1なのに
'2014-12-01'から'2015-02-01'が12/1-2/1というのはちょっと道理が合わない気がします
2/1-12/1じゃないのでしょうか?

一応やり方としては@xが@a-@b間だとして
@a<=@bなら@x between @a and @b
@a>@bなら(@a<=@x or @b<=@x)とすれば拾えますが

投稿2017/05/12 00:29

yambejp

総合スコア114572

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Praline

2017/05/12 00:59

やはり年を超えたか判定するのが無難でしょうか… ユーザーの登録日や誕生日のみの情報が欲しく、登録年は考慮しない処理を考えていました。
yambejp

2017/05/12 01:30

では例えば '2014-01-01'から'2014-02-01'が1/1~2/1だとして前後をひっくり返して '2014-02-01'から'2014-01-01'とした場合は、2/1~12/31+1/1でよいのですね?
Praline

2017/05/12 02:37

その認識で問題ないです。 ただ、今日基準から何日間、という判定にするので、基本的にはそのような運用は発生しない前提です。
guest

0

where区でifを使いましたが...

sql

1select * from A 2where if ( DATE_FORMAT('2014-01-01', '%m%d') <= DATE_FORMAT('2015-02-01', '%m%d'), 3 (DATE_FORMAT(MMDD, '%m%d') between DATE_FORMAT('2014-01-01', '%m%d') and DATE_FORMAT('2015-02-01', '%m%d')), 4 (DATE_FORMAT(MMDD, '%m%d') >= DATE_FORMAT('2014-01-01', '%m%d') OR 5 DATE_FORMAT(MMDD, '%m%d') <= DATE_FORMAT('2015-02-01', '%m%d')) 6); 7 8select * from A 9where if ( DATE_FORMAT('2014-12-01', '%m%d') <= DATE_FORMAT('2015-02-01', '%m%d'), 10 (DATE_FORMAT(MMDD, '%m%d') between DATE_FORMAT('2014-12-01', '%m%d') and DATE_FORMAT('2015-02-01', '%m%d')), 11 (DATE_FORMAT(MMDD, '%m%d') >= DATE_FORMAT('2014-12-01', '%m%d') OR 12 DATE_FORMAT(MMDD, '%m%d') <= DATE_FORMAT('2015-02-01', '%m%d')) 13);

投稿2017/05/11 22:43

A.Ichi

総合スコア4070

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問