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

MySQLで複数の行レコードを1行にまとめる方法|CASE WHENを使ったクロス集計の基本

MySQLでは、複数の行に分かれているレコードを、条件ごとに1行へまとめて表示したいケースがあります。たとえば「同じ会社の従業員データを国別に横並びで表示したい」場合などです。

こうした処理には CASE WHEN を使うのが定番の方法です。本記事では、実際にテーブルを作成し、複数の行レコードを1行に結合する手順をサンプルSQL付きで解説します。

1. サンプルテーブルを作成する

まずは、会社名・従業員名・国名を持つテーブルを作成します。

mysql> create table demo68
-> (
-> id int not null auto_increment primary key,
-> company_name varchar(50),
-> employee_name varchar(50),
-> country_name varchar(50)
-> );
Query OK, 0 rows affected (1.86 sec)

2. テストデータを挿入する

次に、INSERT文を使ってレコードを登録します。ここでは同じ会社(Google)の従業員3名を、それぞれ異なる国名とともに挿入しています。

mysql> insert into demo68(company_name,employee_name,country_name)
values('Google','John','US');
Query OK, 1 row affected (0.29 sec)

mysql> insert into demo68(company_name,employee_name,country_name)
values('Google','Bob','UK');
Query OK, 1 row affected (0.10 sec)

mysql> insert into demo68(company_name,employee_name,country_name)
values('Google','David','AUS');
Query OK, 1 row affected (0.08 sec)

3. 登録したデータを確認する

SELECT文でテーブルの中身を確認してみましょう。

mysql> select *from demo68;

実行すると、以下のように3行のレコードが表示されます。

+----+--------------+---------------+--------------+
| id | company_name | employee_name | country_name |
+----+--------------+---------------+--------------+
| 1  | Google       | John          | US           |
| 2  | Google       | Bob           | UK           |
| 3  | Google       | David         | AUS          |
+----+--------------+---------------+--------------+
3 rows in set (0.00 sec)

4. CASE WHENで行レコードを1行にまとめる

ここからが本題です。以下のクエリでは、CASE WHENで国名ごとに従業員名を振り分け、MAX関数とGROUP BYを組み合わせることで、複数の行を1行にまとめています。

mysql> select
-> company_name,
-> max(case when country_name= 'US' then employee_name end) as
US_Employee_Name,
-> max(case when country_name= 'UK' then employee_name end) as
UK_Employee_Name,
-> max(case when country_name= 'AUS' then employee_name end) as
AUS_Employee_Name
-> from demo68
-> group by company_name;

実行結果は以下の通りです。国別だった3行のデータが、1行に整理されて表示されました。

+--------------+------------------+------------------+-------------------+
| company_name | US_Employee_Name | UK_Employee_Name | AUS_Employee_Name |
+--------------+------------------+------------------+-------------------+
| Google       | John             | Bob              | David             |
+--------------+------------------+------------------+-------------------+
1 row in set (0.05 sec)

仕組みのポイント

  • CASE WHEN:各行に対して「country_nameが'US'ならemployee_nameを返す」という条件判定を行い、該当しない場合はNULLを返します。
  • MAX関数:GROUP BY後のグループ内で、NULL以外の値(つまり条件に一致した従業員名)だけを抽出します。
  • GROUP BY:company_nameごとにグループ化することで、会社単位で1行に集約されます。

この手法は、いわゆる「ピボット(縦持ち→横持ち)変換」の基本的な実装方法です。MySQL 8.0以降ではPIVOT構文は標準提供されていないため、CASE WHEN+集計関数の組み合わせが実務上もっとも広く使われています。列数が多い場合や動的に列を切り替えたい場合は、GROUP_CONCATを使う方法や、アプリケーション側で整形する方法も検討するとよいでしょう。

  1. MySQLで今月のレコードを合計する方法【SUM()とMONTH()関数の使い方】

    MySQLで今月のレコードを合計する方法MySQLで今月のレコードを合計するには、SUM()関数とMONTH()関数を組み合わせて使用します。ここでは、サンプルテーブルを作成し、実際にデータを集計する手順を順番に解説します。1. テーブルを作成するまず、日付と金額を格納するテーブルを作成しましょう。mysql> create table DemoTable1889    (    DueDate date,    Amount int   

  2. MySQLでLIMIT句を使ってページネーション(次の行)を取得する方法

    MySQLでページネーション(特定の範囲の行だけを取得すること)を実現したい場合は、LIMIT句を使用します。LIMIT句では「開始位置(オフセット)」と「取得する行数」を指定できるため、大量のデータの中から必要な部分だけを効率よく取り出せます。この記事では、実際にテーブルを作成し、データを挿入したうえで、次の行を取得するページネーションの具体的な手順を解説します。1. サンプルテーブルを作成するまずはデモ用のテーブルを作成しましょう。以下のSQLでは、自動採番されるidカラムと名前を格納するnameカラムを持つテーブル「demo40」を定義しています。mysql> create tab