MySQLでGROUP BYとHAVING句を使って、グループ内の最大カウント値を持つレコードを表示する方法
MySQLで特定の列の値ごとにグループ化し、その中で最も出現回数(カウント数)が多いレコードを取得したい場合があります。このようなケースでは、GROUP BY句とHAVING句を組み合わせることで簡単に実現できます。本記事では、実際のサンプルコードを通じて、その手順をわかりやすく解説します。
1. サンプルテーブルの作成
まず、検証用のテーブルを作成しましょう。
mysql> create table DemoTable
(
Value int
);
Query OK, 0 rows affected (0.54 sec)2. テーブルへのレコード挿入
次に、INSERT文を使ってテーブルにレコードを挿入します。ここでは、同じ値が複数回出現するようにデータを用意しています。
mysql> insert into DemoTable values(88); Query OK, 1 row affected (0.22 sec) mysql> insert into DemoTable values(88); Query OK, 1 row affected (0.10 sec) mysql> insert into DemoTable values(88); Query OK, 1 row affected (0.09 sec) mysql> insert into DemoTable values(99); Query OK, 1 row affected (0.09 sec) mysql> insert into DemoTable values(99); Query OK, 1 row affected (0.09 sec) mysql> insert into DemoTable values(99); Query OK, 1 row affected (0.10 sec) mysql> insert into DemoTable values(99); Query OK, 1 row affected (0.07 sec) mysql> insert into DemoTable values(100); Query OK, 1 row affected (0.14 sec) mysql> insert into DemoTable values(100); Query OK, 1 row affected (0.07 sec) mysql> insert into DemoTable values(88); Query OK, 1 row affected (0.19 sec) mysql> insert into DemoTable values(88); Query OK, 1 row affected (0.11 sec)
3. テーブル内の全レコードを確認
SELECT文でテーブルの内容を確認してみましょう。
mysql> select *from DemoTable;
このクエリを実行すると、以下のような結果が得られます。
+-------+ | Value | +-------+ | 88 | | 88 | | 88 | | 99 | | 99 | | 99 | | 99 | | 100 | | 100 | | 88 | | 88 | +-------+ 11 rows in set (0.00 sec)
このテーブルには、「88」が5件、「99」が4件、「100」が2件登録されています。
4. 最大カウント値を持つレコードを取得するクエリ
それでは、グループ内で最も出現回数の多い値とそのカウント数を表示するクエリを見ていきましょう。このクエリでは、値ごとにグループ化してカウント数を集計し、そのカウント数を降順(ORDER BY DESC)に並べ替えたうえで、先頭の1件(LIMIT 1)をサブクエリとして取得しています。そして、HAVING句を使って、その最大カウント数と一致するグループだけを絞り込み、結果を新しい列「NumberOfCount」として表示します。
mysql> select Value,count(*) as NumberOfCount
from DemoTable
group by Value
having count(*)=(select count(*) as NumberOfCount
from DemoTable
group by Value
order by NumberOfCount desc
limit 1);このクエリを実行すると、以下のような結果が出力されます。
+-------+---------------+ | Value | NumberOfCount | +-------+---------------+ | 88 | 5 | +-------+---------------+ 1 row in set (0.00 sec)
クエリのポイント解説
このクエリの動作を整理すると、以下の流れになっています。
① 内側のサブクエリ: 値ごとに出現回数を集計し、カウント数の降順に並べ替えて、最大のカウント数だけを1件取得します。
② 外側のクエリ: 値ごとにカウント数を集計し、HAVING句でサブクエリの結果(最大カウント数)と一致するグループのみを抽出します。
この方法を使えば、最頻値(モード)に該当するレコードを他の列の値と一緒に簡単に表示できます。なお、最大カウント数が同数のグループが複数存在する場合も、HAVING句による比較ですべて表示される点が便利です。
-
MySQLで列の値をシャッフルする方法【ORDER BY RAND()の使い方】
MySQLでテーブル内のレコード(列の値)をランダムに並べ替えたい場合は、ORDER BY RAND()を使用します。この記事では、実際にテーブルを作成し、データを挿入して、シャッフルの動作を手順ごとに確認していきましょう。 1. テーブルの作成 まず、以下のコマンドでサンプル用のテーブルを作成します。 mysql> create table DemoTable1557 -> ( -> SubjectId int NOT NULL AUTO_INCREMENT PRIMARY KEY, -> SubjectName varchar(20) -&
-
MySQLで1つのINSERT文を使って列に複数の値を一括挿入する方法
はじめにMySQLでは、1つのINSERT文を繰り返し実行しなくても、単一のクエリだけで同じ列に複数の値を挿入できます。VALUES句の後ろに、挿入したい値をカンマ区切りのタプル(行)として列挙するだけです。この方法はデータベースへの接続回数を減らせるため、大量のデータを登録する際にパフォーマンス面でも大きなメリットがあります。基本構文複数の値を1つの列に挿入する場合の基本構文は以下のとおりです。INSERT INTO テーブル名 VALUES(値1),(値2),...,(値N);このように、各値を丸括弧で囲み、カンマ(,)で区切って並べることで、1回のクエリで複数行をまとめて挿入できます。実