2つのMySQLテーブルのデータを比較して差分(不一致行)を抽出する方法
データ移行の際など、2つのテーブル間で一致しないデータ(差分)を特定したい場面はよくあります。そんなときは、テーブル同士を比較することで、片方にのみ存在するレコードを簡単に見つけられます。
比較対象となるテーブルの準備
ここでは、「students」と「student1」という2つのテーブルを例に説明します。まず、それぞれのテーブルの中身を確認してみましょう。
mysql> Select * from students; +--------+--------+----------+ | RollNo | Name | Subject | +--------+--------+----------+ | 100 | Gaurav | Computer | | 101 | Raman | History | | 102 | Somil | Computer | +--------+--------+----------+ 3 rows in set (0.00 sec) mysql> select * from student1; +--------+--------+----------+ | RollNo | Name | Subject | +--------+--------+----------+ | 100 | Gaurav | Computer | | 101 | Raman | History | | 102 | Somil | Computer | | 103 | Rahul | DBMS | | 104 | Aarav | History | +--------+--------+----------+ 5 rows in set (0.00 sec)
見ての通り、「students」テーブルには3件、「student1」テーブルには5件のレコードが登録されています。次に、これら2つのテーブルを比較して、一致しない行だけを結果として取得するクエリを見ていきましょう。
差分を抽出するクエリ
以下のクエリを実行すると、2つのテーブルを比較し、どちらか一方にしか存在しない行を抽出できます。
mysql> Select RollNo,Name,Subject from(select RollNo,Name,Subject from students union all select RollNo,Name,Subject from Student1)as std GROUP BY RollNo,Name,Subject HAVING Count(*) = 1 ORDER BY RollNo; +--------+-------+---------+ | RollNo | Name | Subject | +--------+-------+---------+ | 103 | Rahul | DBMS | | 104 | Aarav | History | +--------+-------+---------+ 2 rows in set (0.02 sec)
クエリの仕組み
- UNION ALL: 2つのテーブルの全行を縦に結合します(重複行もそのまま保持されます)。
- GROUP BY: RollNo・Name・Subject の組み合わせごとに行をグループ化します。
- HAVING Count(*) = 1: 出現回数が1回だけの行、つまりどちらか一方のテーブルにしか存在しない行だけを残します。
- ORDER BY RollNo: 結果を見やすくするため、学籍番号順に並べ替えています。
実行結果から、student1テーブルにのみ存在する「Rahul(RollNo: 103)」と「Aarav(RollNo: 104)」の2行が差分として検出されました。両方のテーブルに存在する行は出現回数が2回になるため、自動的に結果から除外されます。
補足:LEFT JOINを使った代替方法
UNION ALLを使う方法以外にも、LEFT JOINとNULL判定を組み合わせて差分を抽出する方法があります。例えば、studentsテーブルに存在しないstudent1テーブルの行を取得したい場合は、次のように記述します。
SELECT s1.RollNo, s1.Name, s1.Subject FROM student1 s1 LEFT JOIN students s ON s1.RollNo = s.RollNo WHERE s.RollNo IS NULL;
この方法は、特定のキーカラムを基準に片方向の差分を確認したい場合に便利です。一方で、UNION ALL+GROUP BYの方法は、双方向の差分を1つのクエリで一度に取得できるというメリットがあります。用途に応じて使い分けるとよいでしょう。
-
MySQLの1つのクエリで複数テーブルの行数を同時にカウントする方法
はじめに MySQLでは、サブクエリ(スカラーサブクエリ)を組み合わせることで、1つのSELECT文で複数のテーブルの行数を同時に取得できます。この記事では、実際にテーブルを作成し、データを挿入して、2つのテーブルの行数を1回のクエリでカウントする手順を解説します。 手順1:1つ目のテーブルを作成する まず、以下のようにテーブルを作成します。 mysql> create table DemoTable1 ( Name varchar(40) ); Query OK, 0 rows affected (0.81 sec) レコードの挿入 INSERTコマンドを使って、いくつかの
-
PythonとMySQLでテーブルの自己結合(SELF JOIN)を実行する方法を解説
SQLでは、共通の列や指定した条件に基づいて2つのテーブルを結合できます。結合には内部結合(INNER JOIN)、外部結合(OUTER JOIN)などさまざまな種類がありますが、本記事ではその中でも「自己結合(SELF JOIN)」について詳しく解説します。自己結合とは、その名の通り、テーブル自身と自分自身を結合する操作のことです。同じテーブルの2つのコピーの間で結合が実行され、何らかの条件に基づいてテーブル内の行同士がマッチングされます。自己結合の基本構文SELECT a.column1, b.column2 FROM table_name a, table_name b WHERE co