MySQLでLEFT JOINを使ってテーブルBに存在しないテーブルAのレコードを抽出する方法
MySQLにおいて、テーブルAには存在するが、テーブルBには存在しないレコードを抽出したい場合、LEFT JOINとIS NULLを組み合わせる方法が最も一般的です。この記事では、具体的な構文とサンプルデータを使った実行例をわかりやすく解説します。
基本的な構文
LEFT JOINを使った差分抽出の基本構文は以下の通りです。
SELECT テーブルA.* FROM テーブルA LEFT JOIN テーブルB ON テーブルA.列名 = テーブルB.列名 WHERE テーブルB.列名 IS NULL;
このクエリの仕組みはシンプルです。まずLEFT JOINによってテーブルAの全レコードを保持したままテーブルBと結合します。その後、結合先のテーブルBの値がNULLになっている行、つまりテーブルBに対応するデータが存在しない行だけをWHERE句で絞り込んでいます。
サンプルデータの準備
テーブルAの作成
まず、検証用にテーブルAを作成します。
mysql> CREATE TABLE table_A (
-> Value INT
-> );
Query OK, 0 rows affected (1.10 sec)続いて、INSERT文でレコードを挿入します。
mysql> INSERT INTO table_A VALUES(10); Query OK, 1 row affected (0.32 sec) mysql> INSERT INTO table_A VALUES(15); Query OK, 1 row affected (0.10 sec) mysql> INSERT INTO table_A VALUES(35); Query OK, 1 row affected (0.21 sec) mysql> INSERT INTO table_A VALUES(45); Query OK, 1 row affected (0.13 sec)
SELECT文で登録内容を確認してみましょう。
mysql> SELECT * FROM table_A;
実行結果は以下の通りです。
+-------+ | Value | +-------+ | 10 | | 15 | | 35 | | 45 | +-------+ 4 rows in set (0.00 sec)
テーブルBの作成
次に、比較対象となるテーブルBを作成します。
mysql> CREATE TABLE table_B (
-> Value INT
-> );
Query OK, 0 rows affected (0.51 sec)こちらにもINSERT文でレコードを追加します。
mysql> INSERT INTO table_B VALUES(10); Query OK, 1 row affected (0.18 sec) mysql> INSERT INTO table_B VALUES(20); Query OK, 1 row affected (0.12 sec) mysql> INSERT INTO table_B VALUES(35); Query OK, 1 row affected (0.23 sec) mysql> INSERT INTO table_B VALUES(60); Query OK, 1 row affected (0.12 sec)
テーブルBの中身を確認します。
mysql> SELECT * FROM table_B;
実行結果は以下の通りです。
+-------+ | Value | +-------+ | 10 | | 20 | | 35 | | 60 | +-------+ 4 rows in set (0.00 sec)
LEFT JOINによる差分抽出の実行
それでは、実際に「テーブルAには存在するが、テーブルBには存在しないレコード」をLEFT JOINで抽出してみましょう。
mysql> SELECT table_A.*
-> FROM table_A
-> LEFT JOIN table_B ON table_A.Value = table_B.Value
-> WHERE table_B.Value IS NULL;実行結果は以下の通りです。
+-------+ | Value | +-------+ | 15 | | 45 | +-------+ 2 rows in set (0.04 sec)
結果の解説
テーブルAには「10」「15」「35」「45」の4件が存在し、テーブルBには「10」「20」「35」「60」の4件が存在します。両テーブルを比較すると、テーブルB側に存在しないテーブルAの値は「15」と「45」の2件です。上記の実行結果もこれと一致しており、LEFT JOINとIS NULLを組み合わせた差分抽出が正しく機能していることが確認できます。
補足:NOT EXISTSとの使い分け
同様の処理はNOT EXISTSサブクエリでも実現できます。一般的に、大量のデータを扱う場合はLEFT JOIN方式がパフォーマンス面で有利になることが多い一方、NOT EXISTSの方は意図が明確で読みやすいというメリットがあります。用途や環境に応じて使い分けるとよいでしょう。
-
MySQLでテーブルの重複を除いたレコードから平均値を取得するクエリの書き方
MySQLで平均値を求めるには AVG() 関数を使用します。さらに DISTINCT と組み合わせることで、重複しているレコードを除外した状態で平均を計算することができます。この記事では、実際にサンプルテーブルを作成しながら、個別(ユニーク)なレコードから平均値を取得する方法を解説します。サンプルテーブルの作成まず、以下のクエリでテーブルを作成します。mysql> create table DemoTable1934 ( StudentName varchar(20), StudentMarks int ); Query OK, 0 rows affec
-
MySQLで特定の値が存在しないレコードを抽出する方法(NOT IN句の使い方)
MySQLでテーブルから「特定の値を含まない」レコードだけを取得したい場合は、NOT IN() 句を使用します。この記事では、実際にサンプルテーブルを作成しながら、NOT IN句の基本的な使い方を解説します。サンプルテーブルの作成まず、学生情報を格納するためのテーブルを作成しましょう。StudentId を主キー(AUTO_INCREMENT)とし、StudentName カラムを持つシンプルなテーブルです。mysql> create table DemoTable1991 ( StudentId int NOT NULL AUTO_INCREMENT PRIMARY KEY,