技術メモ

書いておぼえるブログ

【MySQL】日付を操作したい

状況

指定範囲の期間でレコードを絞り込みたい。たとえば、きのう、先週、先月。

解決

日付操作用の関数を組み合わせる。 DATE_SUBYEARWEEKDATE_FORMATなどなど。

コード

CREATE TABLE articles (
  id int,
  title varchar,
  created_at date
)

本日から8〜14日の間に作成されたレコードを取得する。

SELECT *
FROM articles
WHERE date = BETWEEN DATE_SUB( CURRENT_DATE(), interval 14day ) AND DATE_SUB( CURRENT_DATE(), interval 8 day ); 

あるいは週番号を西暦につなげて返すYEARWEEKをつかえばもっと簡単だ。

SELECT *
FROM articles
WHERE YEARWEEK(date) = YEARWEEK( CURRENT_DATE()) -1; 

このときYEARWEEKは直に引き算できる。

SELECT YEARWEEK(CURRENT_DATE())-1;
-- 201826 (2018/07/12時点)

ハマりポイント

除算できない形式に対して除算してしまう。返り値がおかしくなるかエラーになる。

例:yyyy-mm-dd形式の文字列を除算する

SELECT DATE_FORMAT( CURRENT_DATE(), '%Y-%m-%d') -1;
-- 2018-07-12 ではなく 2017が返ってくる!!!

だが次の場合は期待する結果が得られる。日付フォーマットからハイフンの区切りを省いた。

SELECT DATE_FORMAT( CURRENT_DATE(), '%Y%m%d') -1;
-- 20180712 - 1 => 20180711  (^^)

さらに年月も計算できる。

除算

SELECT DATE_FORMAT( CURRENT_DATE(), '%Y%m') -1;
-- 201807 - 1 => 201806  (^^)

加算

SELECT DATE_FORMAT( CURRENT_DATE(), '%Y%m') +1;
-- 201807 + 1 => 201807

雑感

うっかり文字列の日付を直に演算してバグらせてしまった。何がおかしいのかしばらくわからなかった。正しいと思っているコードのおかしい箇所に気づくのはむずかしい。