MySQL
 Computer >> コンピューター >  >> プログラミング >> MySQL

MySQLで日付の範囲から日付リストを生成する方法

MySQLで日付の範囲から日付リストを生成する方法

MySQLでは、adddate()関数と複数の派生テーブル(数字テーブル)を組み合わせたクエリを使うことで、指定した期間内のすべての日付を簡単に生成できます。

以下の例では、'2016-12-15'から'2016-12-31'までの日付を一覧として生成しています。

日付を生成するSQLクエリ

mysql> select * from
    -> (select adddate('1970-01-01',t4*10000 + t3*1000 + t2*100 + t1*10 + t0) gen_date from
    -> (select 0 t0 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
    -> (select 0 t1 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
    -> (select 0 t2 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
    -> (select 0 t3 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
    -> (select 0 t4 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v
    -> Where gen_date between '2016-12-15' and '2016-12-31'
    -> ;
+------------+
| gen_date   |
+------------+
| 2016-12-15 |
| 2016-12-16 |
| 2016-12-17 |
| 2016-12-18 |
| 2016-12-19 |
| 2016-12-20 |
| 2016-12-21 |
| 2016-12-22 |
| 2016-12-23 |
| 2016-12-24 |
| 2016-12-25 |
| 2016-12-26 |
| 2016-12-27 |
| 2016-12-28 |
| 2016-12-29 |
| 2016-12-30 |
| 2016-12-31 |
+------------+
17 rows in set (0.30 sec)

クエリの仕組み

このクエリのポイントは、0〜9の数字だけを持つ5つのサブクエリ(t0〜t4)をクロス結合している点です。これにより、0から99999までの連続した数値が作られます。

次に、その数値を基準日である '1970-01-01'adddate() 関数で加算することで、連続した日付を大量に生成しています。最後に WHERE 句の BETWEEN で目的の範囲だけに絞り込む仕組みです。

生成したい期間が短い場合は、数字テーブルの数を減らすことでクエリをシンプルにできます。たとえば1年分程度であれば、3つのテーブル(0〜999)でも十分対応可能です。

MySQL 8.0以降なら再帰CTEも便利

MySQL 8.0以降を使用している場合は、再帰CTE(共通テーブル式)を使うと、より直感的に記述できます。

WITH RECURSIVE dates AS (
  SELECT '2016-12-15' AS gen_date
  UNION ALL
  SELECT gen_date + INTERVAL 1 DAY
  FROM dates
  WHERE gen_date + INTERVAL 1 DAY <= '2016-12-31'
)
SELECT * FROM dates;

開始日から1日ずつ加算しながら終了日に達するまで行を生成するため、コードの意図が分かりやすく、メンテナンス性も向上します。用途やバージョンに応じて使い分けると良いでしょう。

  1. MySQLビューを使って日付範囲から連続日付を生成する方法

    MySQLには、他のデータベース製品のような連番生成関数やカレンダーテーブルが標準搭載されていないため、指定期間の全日付を一覧表示したい場合はひと工夫必要です。本記事ではビュー(VIEW)を複数組み合わせて、指定した日付範囲の連続した日付を動的に生成する方法を解説します。 全体の仕組み この手法は次の3つのステップで構成されます。 0〜9の数字を返すビュー「digits」を作成する digitsを掛け合わせて0〜9999の連続数値を持つビュー「numbers」を作成する 数値を日付演算に変換して日付リストを返すビュー「dates1」を作成する ステップ1:0〜9の数字を持つ「digit

  2. MySQLでテーブルの最後の10件のレコードを取得する方法

    MySQLでテーブルの末尾にある10行(最新の10件)を取得したい場合は、SELECT文とLIMIT句を組み合わせたサブクエリを利用します。この記事では、実際にテーブルを作成し、データを挿入しながら、最後の10件を取得するクエリの手順を具体的に解説します。 1. サンプルテーブルの作成 まず、動作確認用のテーブルを作成します。 mysql> create table Last10RecordsDemo -> ( -> id int, -> name varchar(100) -> ); Query OK, 0 rows affected