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

MySQLで2つのテーブルを比較して欠落しているIDを抽出する方法

MySQLで2つのテーブルを比較し、片方のテーブルに存在しないID(欠落しているID)を取得したい場合は、サブクエリNOT IN句を組み合わせるのが基本的な方法です。

基本構文

以下が、2つのテーブルを比較して欠落しているIDを返すための基本構文です。

SELECT テーブル名1.IDカラム名 FROM テーブル名1
WHERE IDカラム名 NOT IN (SELECT テーブル名2.IDカラム名 FROM テーブル名2);

この構文では、サブクエリで2つ目のテーブルに存在するIDの一覧を取得し、1つ目のテーブルの中でその一覧に含まれないIDだけを抽出しています。

それでは、実際にサンプルデータを使って動作を確認してみましょう。

ステップ1:1つ目のテーブル(First_Table)を作成する

まず、比較元となるテーブルを作成します。

mysql> create table First_Table
    -> (
    -> Id int
    -> );
Query OK, 0 rows affected (0.88 sec)

次に、INSERT文でレコードを挿入します。

mysql> insert into First_Table values(1);
Query OK, 1 row affected (0.68 sec)
mysql> insert into First_Table values(2);
Query OK, 1 row affected (0.29 sec)
mysql> insert into First_Table values(3);
Query OK, 1 row affected (0.20 sec)
mysql> insert into First_Table values(4);
Query OK, 1 row affected (0.20 sec)

SELECT文ですべてのレコードを確認しましょう。

mysql> select *from First_Table;

実行結果は以下の通りです。

+------+
| Id   |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
+------+
4 rows in set (0.00 sec)

First_Tableには「1」「2」「3」「4」の4件のIDが登録されました。

ステップ2:2つ目のテーブル(Second_Table)を作成する

続いて、比較先となるテーブルを作成します。

mysql> create table Second_Table
    -> (
    -> Id int
    -> );
Query OK, 0 rows affected (0.60 sec)

こちらにもINSERT文でレコードを挿入します。

mysql> insert into Second_Table values(2);
Query OK, 1 row affected (0.19 sec)
mysql> insert into Second_Table values(4);
Query OK, 1 row affected (0.20 sec)

登録内容を確認しておきましょう。

mysql> select *from Second_Table;

実行結果は以下の通りです。

+------+
| Id   |
+------+
|    2 |
|    4 |
+------+
2 rows in set (0.00 sec)

Second_Tableには「2」と「4」の2件のみ登録されています。つまり、First_Tableにある「1」と「3」がSecond_Tableには存在しないIDということになります。

ステップ3:2つのテーブルを比較して欠落しているIDを取得する

いよいよ、NOT IN句とサブクエリを使って比較クエリを実行します。

mysql> select First_Table.Id from First_Table where
    -> First_Table.Id NOT IN(select Second_Table.Id from Second_Table);

実行結果は以下の通りです。

+------+
| Id   |
+------+
|    1 |
|    3 |
+------+
2 rows in set (0.00 sec)

期待どおり、First_Tableには存在するもののSecond_Tableには存在しないID「1」と「3」が返されました。

補足:パフォーマンスを考慮した代替手段

NOT IN句は直感的でわかりやすい一方、対象カラムにNULL値が含まれる場合や、レコード数が非常に多い場合は意図しない結果やパフォーマンス低下につながることがあります。そのようなケースでは、LEFT JOINNOT EXISTSを使う方法も検討するとよいでしょう。

-- LEFT JOIN を使った例
SELECT f.Id FROM First_Table f
LEFT JOIN Second_Table s ON f.Id = s.Id
WHERE s.Id IS NULL;
-- NOT EXISTS を使った例
SELECT f.Id FROM First_Table f
WHERE NOT EXISTS (
  SELECT 1 FROM Second_Table s WHERE s.Id = f.Id
);

どちらの方法でも同じ結果が得られますので、データ量やNULLの扱い方に応じて最適な方法を選択してください。

  1. 2つのテーブルに対する単一のMySQL SELECTクエリは可能ですか?

    はい、可能です。FROM句にカンマ区切りで複数のテーブル名を指定することで、単一のSELECTクエリで2つのテーブルからデータを取得できます。基本的な構文は以下の通りです。select * from yourTableName1,yourTableName2;なお、この書き方では両テーブルの全行が組み合わされた「クロス結合(直積)」の結果が返される点に注意してください。サンプルテーブルの作成まず、1つ目のテーブルを作成します。mysql> create table DemoTable1    -> (   &nb

  2. MySQLで1つのクエリを使ってSELECTとINSERTを同時に実行する方法

    MySQLでは、INSERT INTO ... SELECT構文とUNION ALLを組み合わせることで、1つのクエリだけで別テーブルからデータを選択(SELECT)し、挿入(INSERT)することができます。本記事では、実際のサンプルコードを使ってその手順をわかりやすく解説します。1. 最初のテーブルを作成するまず、データの挿入先となる最初のテーブルを作成します。以下のクエリを実行してください。mysql> create table DemoTable1 -> ( -> StudentName varchar(20), -> StudentMarks