0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【MySQL】 日付の加算減算(date_add関数)

Last updated at Posted at 2020-01-10

概要

日付を加算減算するのに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')

  1. 変換する際に日付が足りないから、concatを使って文字列結合して"20001201"の文字列データを作成。
  2. str_to_dateで文字列をdate型に変換。

date_add(str_to_date(concat("200011", '01'), '%Y%m%d'), interval 1 month)

  1. 変換する際に日付が足りないから、concatを使って文字列結合して"20001101"の文字列データを作成。
  2. str_to_dateで文字列をdate型に変換。
  3. date_add関数を使って1ヵ月プラスする。

「前者はdate_add使わないしdate型にする必要なくない?」という考えが一瞬頭をよぎったが、「後者の加算したdate型の日付と比較するんだから、date型にしないと比較できないよな」と思い直し、落ち着きを取り戻した。

まとめ

「date_add関数で扱うことができるのはdate型」
関数が扱うことのできるデータ型を把握した上で使わないと、想定通りのデータ取得ができないということがわかった。また、文字列結合や型変換を駆使すれば(無理やりだけど)想定通りの結果を得ることができる、という発見もあって良かった。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?