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を使う方法や、アプリケーション側で整形する方法も検討するとよいでしょう。
-
MySQLで今月のレコードを合計する方法【SUM()とMONTH()関数の使い方】
MySQLで今月のレコードを合計する方法MySQLで今月のレコードを合計するには、SUM()関数とMONTH()関数を組み合わせて使用します。ここでは、サンプルテーブルを作成し、実際にデータを集計する手順を順番に解説します。1. テーブルを作成するまず、日付と金額を格納するテーブルを作成しましょう。mysql> create table DemoTable1889 ( DueDate date, Amount int
-
MySQLでLIMIT句を使ってページネーション(次の行)を取得する方法
MySQLでページネーション(特定の範囲の行だけを取得すること)を実現したい場合は、LIMIT句を使用します。LIMIT句では「開始位置(オフセット)」と「取得する行数」を指定できるため、大量のデータの中から必要な部分だけを効率よく取り出せます。この記事では、実際にテーブルを作成し、データを挿入したうえで、次の行を取得するページネーションの具体的な手順を解説します。1. サンプルテーブルを作成するまずはデモ用のテーブルを作成しましょう。以下のSQLでは、自動採番されるidカラムと名前を格納するnameカラムを持つテーブル「demo40」を定義しています。mysql> create tab