SQLで「exists」が出てきた事はありませんか?出てきてその動きが分かりにくく困った事はないでしょうか?
SQLでの「exists」は少し他のコマンドとは違いますのでここにまとめておきます。
exists句は奥が深いので今回は基礎の部分だけにしておきます。
windowsのプロンプトで使用できるbatやpythonやphpを使用して、業務効率化やWebサイトを作成しております。javaやシェルスクリプトなど、様々なプログラミングを行った実績ありの筆者です。
実際に「exists句」や否定形の「not exists句」を使用して動きも見ていくのでわかりやすくなっています。
SQLで「exists」と「not exists」の使い方
SQLで「exists」と「not exists」の基礎構文
SQLで「exists句」を使用する時の基礎構文は以下となります。
select * from テーブル名 where exists (サブクエリ);
SQLで「not exists句」を使用する時の基礎構文はexistsの前に「not」を入れるだけです。
select * from テーブル名 where not exists (サブクエリ);
SQLでの「exists」と「not exists」の説明
existsの特徴1は引数が1つでサブクエリになるという事です。
existsの特徴2はwhereのカラム(existsの左側)を指定しない事です。
カラムを指定しない理由はサブクエリで求めたレコードがある(TRUE)かない(FALSE)かの2択だからです。だからカラムを指定しない
では実際にSQLで「exists」と「not exists」を使用してみましょう!
SQLで「exists」と「not exists」を使ってみる
SQL実施環境解説
実施する際の環境を説明します。
以下の2つのテーブルがあるとします。
テニスを行った人の氏名、名前、年齢を表示してみます。
SQLで「exists」を使ってみる
以下のSQLコマンドを実行してみます。
SELECT
`氏名`,
`名前`,
`年齢`
FROM
`人員` j
WHERE
EXISTS(
SELECT
1
FROM
`点数表` t
WHERE
j.`番号` = t.`番号` AND t.`競技id` = 3
);
SQL文の説明
SELECTで表示するものを記述しています。
FROMで表示するテーブルを記述しています。
WHEREで「EXISTS」を指定しています。その後にサブクエリをいれています。
サブクエリのSELECTには「1」を記述していますが「*」でも良いです。
サブクエリのFROMでサブクエリするテーブルを記述しています。
サブクエリのWHEREで条件を記述しています。
サブクエリでは相関サブクエリをいれますので、表示するテーブルの「番号」と検索するテーブルの「番号」をイコールにしてテーブルをつなげています。
ANDで繋げて条件の競技名テニスに対応している「競技id」が3のものを指定しています。
これで「競技id」が3になっている番号のレコードが真(TRUE)になり表示されます。
SQLで「exists」を実施した結果
では先程のSQL文を実施してみます。
テニスをしている4人が表示されました。
SQLで「not exists」を使ってみる
では今度は「not exists」を実施します。先程のSQL文の「exists」を「not exists」に変更したものが以下となります。
SELECT
`氏名`,
`名前`,
`年齢`
FROM
`人員` j
WHERE NOT
EXISTS(
SELECT
1
FROM
`点数表` t
WHERE
j.`番号` = t.`番号` AND t.`競技id` = 3
);
SQL構文の説明は「exists」と同じなので省略します。
SQLで「not exists」を実施した結果
では先程のSQL文を実行します。
テニスをしている人以外が表示されました。
SQLで「exists」は「in」で代用可能
実は「exists句」と「not exists句」は「in句」でも対応可能です。
「in句」を使用して同じことを行ってみます。以下のSQL構文を見て下さい。
SELECT
`氏名`,
`名前`,
`年齢`
FROM
`人員` j
WHERE
`番号` IN(
SELECT
`番号`
FROM
`点数表` t
WHERE
t.`競技id` = 3
);
「exists」を使用したSQL文からの変更点としては以下があります。
- 「exists」を「in」に変更する
- 「in」の前にカラムを記入する
- WHERE以降は競技がテニスの「競技id」が3のものを指定
ではexistsからinに変更したSQL文を実行してみます。
「exists」の時と同じ結果になりました。
では「not exists」も「not in」に変更してみます。変更したSQL文は以下となります。
SELECT
`氏名`,
`名前`,
`年齢`
FROM
`人員` j
WHERE
`番号` NOT IN(
SELECT
`番号`
FROM
`点数表` t
WHERE
t.`競技id` = 3
);
ではこのSQL文を実行してみます。
こちらも「not exists」と同じ結果となりました。
SQLでexistsとinではどちらを使う
ではSQLでは「exists」と「in」どちらを使用した方が良いのでしょうか?
回答はMySQLではexistsを使う、oracleでは同じだけどexists使う
理由は処理速度が違うからです。「exists」MySQLの場合は処理がはやい
oracleは処理速度は同じと書いているのでどちらでも良いですが、MySQLと合わせてexistsを使用するにしました。
なので「exists」と「in」では「exists」を使用した方が良いとなりました。
SQLで「exists」と「not exists」の使い方のまとめ
SQLで「exists」と「not exists」の基礎構文
SQLで「exists句」を使用する時の基礎構文は以下となります。
select * from テーブル名 where exists (サブクエリ);
SQLで「not exists句」を使用する時の基礎構文は、existsの前にnotを入れるだけです。
select * from テーブル名 where not exists (サブクエリ);
「in」でも対応可能ですが「exists」と「in」では「exists」を使用した方が良い。
今回使用したexistsを利用したSQL例文は以下です。
SELECT
`氏名`,
`名前`,
`年齢`
FROM
`人員` j
WHERE
EXISTS(
SELECT
1
FROM
`点数表` t
WHERE
j.`番号` = t.`番号` AND t.`競技id` = 3
);
今回はSQLでexistsを使用してみました。