概要
日付を加算減算するのにdate_add関数を使ったが、ハマったのでメモ。
やりたいこと
「誕生日 = パラメータで渡ってくる日付+1ヵ月」という条件で、情報を取得したい。
(パラメータで渡ってくる日付は6字のString)
まずは下準備
1:テーブル作成
mysql> create table test
-> (
-> id int not null auto_increment,
-> name varchar(20) not null,
-> birthday varchar(6) not null,
-> primary key (id)
-> );
Query OK, 0 rows affected (0.03 sec)
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| test |
+----------------+
1 row in set (0.00 sec)
2:データ作成
mysql> insert into test
-> values
-> (null,"山田","200012"),
-> (null,"丸亀","199304"),
-> (null,"民芸","198502");
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from test;
+----+--------+----------+
| id | name | birthday |
+----+--------+----------+
| 1 | 山田 | 200012 |
| 2 | 丸亀 | 199304 |
| 3 | 民芸 | 198502 |
+----+--------+----------+
3 rows in set (0.00 sec)
いざ実践!
「誕生日=パラメータで渡ってくる日付+1ヵ月」という条件で、情報を取得したい!
name="山田" のデータが取れるよう、パラメータで "200011" を渡して、select文を実行する。(name="山田"のbirthdayは"200012"だから、パラメータで "200011" を渡す。)
mysql> select
-> *
-> from
-> test
-> where
-> birthday = date_add("200011", interval 1 month)
-> ;
Empty set, 1 warning (0.00 sec)
とれてなーーーい!!!
原因
エラー発生の原因はデータ型だった。date_add関数はdate型を扱う関数。パラメータとbirthdayは6字のStringだから…date型として扱えていなくてemptyに…。
date_addを使いたいから、全部date型で統一する
とにかく日付の加減減算がしたいので、パラメータとbirthdayをdate型に変換して実行する。Stringをdate型に変えるときは str_to_date
を、date型には日付も必要だから、ひとまず文字列結合 concat
を使ってむりくりdate型にするぞ!!
mysql> select
-> *
-> from
-> test
-> where
-> str_to_date(concat(birthday, '01'), '%Y%m%d')
-> = date_add(str_to_date(concat("200011", '01'), '%Y%m%d'), interval 1 month)
-> ;
+----+--------+----------+
| id | name | birthday |
+----+--------+----------+
| 1 | 山田 | 200012 |
+----+--------+----------+
1 row in set (0.00 sec)
うぇーーーーい!!きたーーーーー!!
もうちょっと詳しく解説
str_to_date(concat(birthday, '01'), '%Y%m%d')
- 変換する際に日付が足りないから、concatを使って文字列結合して"20001201"の文字列データを作成。
- str_to_dateで文字列をdate型に変換。
date_add(str_to_date(concat("200011", '01'), '%Y%m%d'), interval 1 month)
- 変換する際に日付が足りないから、concatを使って文字列結合して"20001101"の文字列データを作成。
- str_to_dateで文字列をdate型に変換。
- date_add関数を使って1ヵ月プラスする。
「前者はdate_add使わないしdate型にする必要なくない?」という考えが一瞬頭をよぎったが、「後者の加算したdate型の日付と比較するんだから、date型にしないと比較できないよな」と思い直し、落ち着きを取り戻した。
まとめ
「date_add関数で扱うことができるのはdate型」
関数が扱うことのできるデータ型を把握した上で使わないと、想定通りのデータ取得ができないということがわかった。また、文字列結合や型変換を駆使すれば(無理やりだけど)想定通りの結果を得ることができる、という発見もあって良かった。