SQLで存在チェックをするには?
SQLでデータやレコードが存在するかどうか、チェックしたい場合があるかと思います。
この記事では、データの存在チェックをするための方法について見ていきましょう。
存在チェックをするには、大きく分けて次の3つの方法があります。
- LIMIT句
- TOP句
- EXISTS演算子
1つずつ詳細や使い方を説明しますね。
(1)LIMIT句
LIMIT句は、 取得するデータ数の上限を設定できます。
SQLでデータの存在をチェックする際に、全件を取得するのは効率的ではありません。
そのため、LIMIT句で上限を設定し、「1件でもデータが見つかればデータが存在する」と判断すべきです。
使い方を確認するために、サンプルを用いてみます。
次のテーブルを用意しました。
mysql> SELECT * FROM customer; +-------------+---------------+ | customer_id | customer_name | +-------------+---------------+ | 101 | Suzuki | | 102 | Itou | | 201 | Yusa | | 202 | Oka | | 101 | Kishi | +-------------+---------------+ 5 rows in set (0.01 sec)
上記のテーブルから、customer_id が「101」のデータが存在するかチェックしてみましょう。
LIMIT句を使わずにデータの存在チェックをすると、次のように書けます。
SELECT * FROM customer WHERE customer_id = 101;
上記のSQL文は、WHERE句を使って「customer_id が101のデータ」という条件を設定していますね。
条件に当てはまるデータがあれば、結果として返ります。
SQL文を実行すると、以下のように結果が取得できました。
mysql> SELECT * FROM customer WHERE customer_id = 101; +-------------+---------------+ | customer_id | customer_name | +-------------+---------------+ | 101 | Suzuki | | 101 | Kishi | +-------------+---------------+ 2 rows in set (0.01 sec)
また、COUNT関数を使っても存在チェックが可能です。
次のように記述できます。
SELECT COUNT(*) FROM customer WHERE customer_id = 101;
テーブル内のデータを走査し、customer_id が101のデータがあればカウントしていきます。
SQL文を実行すると、以下のように結果が取得できました。
mysql> SELECT COUNT(*) FROM customer WHERE customer_id = 101; +----------+ | COUNT(*) | +----------+ | 2 | +----------+ 1 row in set (0.01 sec)
どちらの構文もちゃんと存在チェックできています。
しかし、2つの構文はどちらもテーブル内のデータをすべて確認した上で結果を返します。
そのため、テーブル内のデータ量が膨大な数になると、存在チェックするのに時間がかかってしまうのです。
一方、LIMIT句を使って存在チェックをすると、1つでも該当データが見つかった時点で走査が終了します。
よって、短時間で存在チェックを行うことができるのです。
同じ要領で、LIMIT句を使ってSQL文を書くと、次のようになります。
SELECT * FROM customer WHERE customer_id = 101 LIMIT 1;
実行結果は次の通りです。
mysql> SELECT * FROM customer WHERE customer_id = 101 LIMIT 1; +-------------+---------------+ | customer_id | customer_name | +-------------+---------------+ | 101 | Suzuki | +-------------+---------------+ 1 row in set (0.00 sec)
データを1つ取得できたので、データが存在していることがわかります。
このように、LIMIT句を使うと効率的にデータの存在チェックができるのです。
LIMIT句については、以下の記事でもていねいに解説しているので、よければ参考にしてみてくださいね。
【関連記事】
▶︎SQLでデータの取得件数を指定する方法!LIMIT句の使い方を確認しよう【MySQL】
(2)TOP句
TOP句は、先頭から指定した値分のデータを取得します。
MySQLでは使用できず、SQL Serverで使える句です。
LIMIT句で紹介した理由の通り、存在チェックの時間短縮になるため効率的な句と言えます。
実行する場合は、次のように記述できます。
SELECT TOP(1) FROM customer WHERE customer_id = 101;
執筆者がSQL Serverを使用していないため、実行結果は省略します。
(3)EXISTS演算子
EXISTS演算子は、データが存在するかどうかを判定する演算子です。
EXISTS演算子は、主に相関副問合せと呼ばれる方法で使用されます。
今回のテーブルで存在チェックする場合には、次のように記述しましょう。
SELECT EXISTS(SELECT * FROM customer WHERE customer_id = 101) AS customer_check;
上記のSQL文を実行すると、次のように結果が取得できます。
mysql> SELECT EXISTS(SELECT * FROM customer WHERE customer_id = 101) AS customer_check; +----------------+ | customer_check | +----------------+ | 1 | +----------------+ 1 row in set (0.01 sec)
「1」と結果が返っているので、データが存在しているのがわかりますね。
実際に、データが存在しない場合は「0」が返ります。
SELECT EXISTS(SELECT * FROM customer WHERE customer_id = 109) AS customer_check; mysql> SELECT EXISTS(SELECT * FROM customer WHERE customer_id = 109) AS customer_check; +----------------+ | customer_check | +----------------+ | 0 | +----------------+ 1 row in set (0.00 sec)
このように、EXISTS演算子を使ってもデータの存在チェックが可能です。
EXISTS演算子についても、以下の記事で詳しく解説していますので、よければ参考にしてください!
【関連記事】
▶︎【MySQL入門】exists句の使い方を理解しよう!データが存在するかをチェック
存在チェック時に複数条件を指定する
SQLのデータの存在チェック時に、条件を複数指定したい場合は「AND」を使いましょう。
WHERE句内の条件でANDを使うと、複数の条件を指定できます。
では、先ほどのテーブルを使って、「customer_id が 101」かつ「customer_nameがKishi」であるデータの存在チェックを行いましょう。
次のように記述できます。
SELECT * FROM customer WHERE customer_id = 101 AND customer_name = 'Kishi' LIMIT 1;
上記のSQL文を実行すると、次の結果が取得できました。
mysql> SELECT * FROM customer WHERE customer_id = 101 AND customer_name = 'Kishi' LIMIT 1; +-------------+---------------+ | customer_id | customer_name | +-------------+---------------+ | 101 | Kishi | +-------------+---------------+ 1 row in set (0.02 sec)
2つの条件のどちらにも当てはまるデータが、取得できています。
「(1)LIMIT句」では、Suzukiが取得されましたが、こちらではKishiのデータが取得されているのがわかります。
ANDは、2つの条件が一致している必要があるため、どちらか一方でも条件に当てはまらなければ、存在チェックはできません。
次のように、「Empty set」と結果が返ります。
mysql> SELECT * FROM customer WHERE customer_id = 101 AND customer_name = 'Itou' LIMIT 1; Empty set (0.01 sec)
どちらか一方の条件に当てはまっていればOKであれば、ANDの代わりに「OR」を使いましょう。
mysql> SELECT * FROM customer WHERE customer_id = 101 OR customer_name = 'Itou' LIMIT 1; +-------------+---------------+ | customer_id | customer_name | +-------------+---------------+ | 101 | Suzuki | +-------------+---------------+ 1 row in set (0.00 sec)
このように、条件の範囲を広げることもできます。
存在チェックした上でデータをINSERTする
ここまで、SQLでデータの存在チェックをする方法を紹介しました。
この章では少し視点を変えて、存在チェックした上でデータをINSERTするやり方を見ていきましょう。
例えば、データが存在するか確認して、存在しない場合だけデータを挿入できると便利ですよね。
データを重複して追加してしまうと、管理が煩雑になるのは明確です。
では実際に、存在チェックに合わせてデータをINSERTする方法を確認します。
基本的な記述方法は、次の通りです。
INSERT INTO テーブル名 SELECT データの値 WHERE NOT EXISTS (SELECT 1 FROM テーブル名 WHERE 条件);
少し複雑ですが、必要な情報を当てはめていけば、正しく処理されます。
SQL文の前半で追加するデータの情報を、後半でデータの存在チェックをしているのがわかればOKです。
では、先ほどのテーブルで実際にデータを追加してみます。
INSERT INTO customer SELECT 301, 'Abe' WHERE NOT EXISTS (SELECT 1 FROM customer WHERE customer_id = 301);
上記のSQLは、customer_idが301のデータがない場合に、データを追加します。
実行するとデータが追加され、テーブルを確認するとデータを確認できるはずです。
mysql> INSERT INTO customer SELECT 301, 'Abe' WHERE NOT EXISTS (SELECT 1 FROM customer WHERE customer_id = 301); Query OK, 1 row affected (0.02 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM customer; +-------------+---------------+ | customer_id | customer_name | +-------------+---------------+ | 101 | Suzuki | | 102 | Itou | | 201 | Yusa | | 202 | Oka | | 101 | Kishi | | 301 | Abe | +-------------+---------------+ 6 rows in set (0.00 sec)
では次に、customer_id は同じで customer_name だけ変えてデータを追加してみます。
mysql> INSERT INTO customer SELECT 301, 'Uno' WHERE NOT EXISTS (SELECT 1 FROM customer WHERE customer_id = 301); Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0
そうすると、「Records: 0」となっており、テーブルを確認してもデータが追加されていないはずです。
データを重複させずに追加できるので、少し複雑なSQLですが覚えておくと良いでしょう!