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

MySQLでGROUP BYとHAVINGを使って、最大日付付きの重複値を抽出する方法

MySQLで「同じ名前が複数回登場するレコード」の中から、それぞれのグループにおける最大の日付を取得したいケースはよくあります。このような場合には、GROUP BY句とHAVING句を組み合わせることで実現できます。

本記事では、サンプルテーブルを作成し、実際にデータを挿入したうえで、重複値ごとの最大日付を表示するクエリの書き方を解説します。

1. サンプルテーブルの作成

まずは、学生名と期日を格納するテーブルを作成しましょう。

mysql> create table DemoTable
    (
    StudentName varchar(100),
    DueDate date
    );
Query OK, 0 rows affected (0.72 sec)

テーブルには StudentName(学生名)と DueDate(期日)の2つのカラムを定義しています。

2. テストデータの挿入

次に、INSERTコマンドを使ってレコードを挿入します。ここでは、同じ学生名が複数回登場するデータを意図的に用意しています。

mysql> insert into DemoTable values('John','2019-01-11');
Query OK, 1 row affected (0.26 sec)
mysql> insert into DemoTable values('Chris','2019-02-11');
Query OK, 1 row affected (0.20 sec)
mysql> insert into DemoTable values('Chris','2019-03-11');
Query OK, 1 row affected (0.19 sec)
mysql> insert into DemoTable values('John','2019-04-11');
Query OK, 1 row affected (0.12 sec)
mysql> insert into DemoTable values('Bob','2019-05-11');
Query OK, 1 row affected (0.17 sec)
mysql> insert into DemoTable values('Bob','2019-06-11');
Query OK, 1 row affected (0.15 sec)
mysql> insert into DemoTable values('Robert','2019-07-11');
Query OK, 1 row affected (0.18 sec)
mysql> insert into DemoTable values('Robert','2019-08-11');
Query OK, 1 row affected (0.17 sec)
mysql> insert into DemoTable values('Robert','2019-09-11');
Query OK, 1 row affected (0.15 sec)

3. 全レコードの確認

SELECT文を使って、テーブル内のすべてのレコードを確認してみましょう。

mysql> select *from DemoTable;

出力結果

+-------------+------------+
| StudentName | DueDate    |
+-------------+------------+
| John        | 2019-01-11 |
| Chris       | 2019-02-11 |
| Chris       | 2019-03-11 |
| John        | 2019-04-11 |
| Bob         | 2019-05-11 |
| Bob         | 2019-06-11 |
| Robert      | 2019-07-11 |
| Robert      | 2019-08-11 |
| Robert      | 2019-09-11 |
+-------------+------------+
9 rows in set (0.00 sec)

このように、JohnとChrisは2件ずつ、Bobも2件、Robertは3件存在していることがわかります。

4. 重複値ごとに最大日付を表示するクエリ

それでは本題です。以下のクエリを実行すると、学生名ごとにグループ化し、そのうちレコード数が2件以上(つまり重複している)グループのみを対象として、最大の日付を表示できます。

mysql> select tbl.StudentName,max(tbl.DueDate) from DemoTable tbl group by tbl.StudentName
having count(*) > 1;

ポイントは以下の2点です。

  • GROUP BY: 学生名(StudentName)ごとにレコードをグループ化します。
  • HAVING count(*) > 1: グループ化後の各グループに対して条件を適用し、レコードが複数存在する(重複している)グループだけを抽出します。

出力結果

+-------------+------------------+
| StudentName | max(tbl.DueDate) |
+-------------+------------------+
| John        | 2019-04-11       |
| Chris       | 2019-03-11       |
| Bob         | 2019-06-11       |
| Robert      | 2019-09-11       |
+-------------+------------------+
4 rows in set (0.00 sec)

結果を見ると、重複しているすべての学生名について、それぞれの最新(最大)の日付が正しく表示されていることが確認できます。例えばRobertの場合、3件のレコードのうち最も新しい 2019-09-11 が返されています。

まとめ

重複値ごとに最大日付を取得したい場合は、GROUP BYでキーとなるカラムを指定し、HAVING count(*) > 1で重複グループだけに絞り込み、MAX()関数で最大値を取得するのが基本のパターンです。WHEREではなくHAVINGを使う点が重要で、これは集計後のグループに対して条件を適用するためです。このパターンは、顧客ごとの最新注文日や、ユーザーごとの直近ログイン日時などを求める際にも応用できる、非常に実用的なテクニックです。

  1. MySQLで結果を日付ごとにグループ化し、重複値の件数を表示するクエリの書き方

    はじめにMySQLでは、GROUP BY句とDATE()関数、COUNT()関数を組み合わせることで、日付単位でレコードをグループ化し、重複する値の件数を簡単に集計できます。ここでは、到着日時ごとに乗客コードを集計する例を通して、その具体的な方法を解説します。1. サンプルテーブルの作成まず、以下のSQLを実行してテーブルを作成します。mysql> create table DemoTable1496-> (-> Id int NOT NULL AUTO_INCREMENT PRIMARY KEY,-> PassengerCode varchar(20),-> A

  2. MySQLでSELECTクエリを使用してデータを挿入(INSERT)する方法

    MySQLでは、INSERT文とSELECTクエリを組み合わせることで、テーブルにデータを挿入することができます。通常、SELECTは既存のテーブルからデータを取得するために使われますが、値を直接指定してINSERTを実行する際にも活用できる便利な手法です。基本構文SELECTクエリを使用してINSERTを実行する場合の構文は以下の通りです。insert into yourTableName(yourColumnName1,yourColumnName2,yourColumnName3,...N) select yourValue1,yourValue2,yourValue3,......N;