PostgreSQL入門!EXISTSとINの違いをSQL初心者向けに徹底解説
生徒
「データの検索を勉強しているのですが、EXISTSとINという命令が出てきました。どちらも何かを探すときに使うみたいですが、どう使い分ければいいんですか?」
先生
「非常に重要なポイントですね。一言で言うと、INは『特定の値がリストの中にあるか』を確認するのに向き、EXISTSは『条件に合うデータがどこかに存在するか』を確認するのに向いています。」
生徒
「うーん、言葉だけだと少し難しいです。パソコンの操作をしたことがない私でもわかるように教えてもらえますか?」
先生
「もちろんです。例えば『出席簿』と『図書カード』をイメージしてみてください。誰が本を借りているか探すとき、やり方が二通りあるんですよ。今日はその違いをゆっくり見ていきましょう。」
1. SQLとは何か?
SQL(エスキューエル)は、データベースと呼ばれる「大量のデータを整理して保存する箱」に対して指示を出すための言語です。例えば、会員名簿の中から特定の人を探したり、新しい人を追加したりするときに使います。プログラミングと聞くと難しく感じるかもしれませんが、SQLは人間に近い言葉で「〇〇の表から××さんを探して」とお願いするような感覚で使えます。
PostgreSQL(ポストグレスキューエル)は、そのSQLを使ってデータを管理するためのソフトの一つで、世界中で非常に多くの会社やサービスで使われています。今回は、その中でも特によく使われる「データの検索」について深掘りしていきます。
エンジニアの必須スキル「SQL」を、 図解と豊富な練習問題でゼロから体系的に学びたい人へ。 MySQLやPostgreSQLなど、各種データベースに対応した不朽の入門書です。
SQL 第2版 ゼロからはじめるデータベース操作をAmazonで見る※ Amazon広告リンク
2. 「IN」の使い方をマスターしよう
まずは「IN(イン)」から説明します。INは、指定したリストの中に値が含まれているかをチェックする命令です。現実の世界で例えるなら、宝探しのようなものです。「この箱の中に、リンゴかバナナかミカンは入っていますか?」と聞くのがINの役割です。
例えば、クラスの生徒名簿(studentsテーブル)があって、特定の出席番号の人だけを抜き出したいときに使います。以下の表を見てみましょう。
id | name | grade
---+----------+-------
1 | 山田太郎 | 1
2 | 佐藤花子 | 2
3 | 鈴木一郎 | 1
4 | 田中次郎 | 3
5 | 伊藤あみ | 2
ここで、「出席番号(id)が1番、3番、5番の人だけを教えてください」という命令をSQLで書いてみます。このように「具体的な値のリスト」を指定するのがINの得意技です。
SELECT *
FROM students
WHERE id IN (1, 3, 5);
この命令を実行すると、データベースは「1番はリストにあるかな?あ、あった!3番は?あった!」と順番に確認してくれます。結果は以下のようになります。
id | name | grade
---+----------+-------
1 | 山田太郎 | 1
3 | 鈴木一郎 | 1
5 | 伊藤あみ | 2
INは、探したいものがハッキリ決まっているときにとても便利です。しかし、探したい対象が何万件、何十万件と増えてくると、リストを全部確認するのに時間がかかってしまうことがあります。
3. 「EXISTS」の仕組みを理解しよう
次に「EXISTS(イグジスツ)」について解説します。日本語では「存在する」という意味です。EXISTSは、INのように「値そのもの」を見るのではなく、「条件に当てはまるデータが向こう側の表に一つでもあるかどうか」を確認します。
これを例えるなら、お店の店員さんに「裏の倉庫に、イチゴ味のアイスはありますか?」と聞くようなものです。店員さんは倉庫に入って、イチゴ味のアイスを「一つでも」見つけたら、すぐに「ありますよ!」と戻ってきます。全部のアイスを数え上げる必要はありません。見つかった瞬間に作業を終えられるのが、EXISTSの賢いところです。
例として、「注文履歴(orders)があるお客さん(customers)だけを表示したい」という場合を考えてみましょう。まずは二つのテーブルを確認します。
【customersテーブル(お客さん名簿)】
customer_id | name
------------+----------
1 | 山田太郎
2 | 佐藤花子
3 | 鈴木一郎
【ordersテーブル(注文履歴)】
order_id | customer_id | item
---------+-------------+--------
101 | 1 | ノート
102 | 1 | 消しゴム
103 | 3 | ペン
ここで、「一回でも注文したことがあるお客さんの名前だけを知りたい」という時にEXISTSを使います。佐藤さんは注文履歴にいないので、表示されないはずです。
SELECT name
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.customer_id
);
このSQLがやっていることは、「お客さん名簿の一人ひとりについて、注文履歴の表にその人のIDがあるか探しに行く」という作業です。見つかった時点で「この人は注文あり!」と確定します。実行結果はこうなります。
name
----------
山田太郎
鈴木一郎
4. INとEXISTSの決定的な違いとは?
さて、ここが一番大切なポイントです。「結局、どう違うの?」という疑問にお答えします。大きな違いは「探し方の効率」と「NULL(ヌル)の扱い」です。
① 探し方の効率(スピード)の違い
INは「リストを全部作ってから、自分と同じものがあるか」を探します。一方、EXISTSは「条件に合うものが一つでも見つかったら合格」という探し方をします。そのため、相手のテーブル(今の例なら注文履歴)が膨大な場合、EXISTSの方が早く終わることが多いです。パソコンで重いデータを扱うプロの人たちは、このスピードの違いをとても気にします。
② NULL(空っぽのデータ)への対応
ここで少し難しい言葉「NULL(ヌル)」が出てきました。これは、データが何も入っていない「空(から)」の状態を指します。パソコンの世界では「0」と「何もない」は別物として扱われます。INを使っているとき、もしリストの中に一つでもNULLが混ざっていると、結果が予想外のもの(何も表示されないなど)になることがあります。一方、EXISTSは「存在するかどうか」だけを見るので、NULLがあっても比較的トラブルが起きにくいという特徴があります。
5. 実践的なクエリで比較してみよう
さらに理解を深めるために、別の例を使ってみましょう。「図書室の本のデータ(books)」と「現在貸し出し中のデータ(rentals)」があるとします。「今、一冊でも借りられている本だけ」をリストアップしてみましょう。
【booksテーブル】
book_id | title | author
--------+----------------+--------
1 | 楽しいSQL | 山田
2 | PostgreSQL入門 | 佐藤
3 | 料理の基本 | 鈴木
4 | 星の王子さま | サン
【rentalsテーブル】
rental_id | book_id | user_name
----------+---------+----------
10 | 2 | 田中
11 | 4 | 高橋
まずは「IN」を使った書き方です。貸し出し中の全てのIDをリストアップして、それと一致する本を探します。
SELECT title
FROM books
WHERE book_id IN (SELECT book_id FROM rentals);
次に「EXISTS」を使った書き方です。「本の一冊ずつについて、貸し出し中リストに名前があるか?」を確認します。
SELECT title
FROM books b
WHERE EXISTS (
SELECT 1
FROM rentals r
WHERE r.book_id = b.book_id
);
どちらも結果は同じになりますが、動作の中身が違います。
title
----------------
PostgreSQL入門
星の王子さま
初心者のうちは、自分が書きやすい方から始めて全く問題ありません。まずは「INは具体的なリストで探す」「EXISTSは条件に合うデータが『あるかないか』で探す」というイメージを大切にしてください。PostgreSQLを触っていくうちに、少しずつ「ここはEXISTSの方がスマートだな」と感じる場面が出てくるはずです。
6. データベース操作で気をつけること
データベースを操作するとき、パソコンが不慣れな方が一番怖いのは「データを消してしまわないか」ということですよね。今回紹介した「SELECT(セレクト)」という命令は、あくまで「データを見るだけ」の命令です。どれだけ試しても、元のデータが壊れたり消えたりすることはありません。安心して色々なクエリを試してみてください。
SQLをマスターするコツは、実際に表をイメージしながら、自分の言葉で「こういうデータが欲しい!」と頭の中で唱えてみることです。PostgreSQLはその願いを叶えてくれる強力なツールになります。INとEXISTSの使い分けができるようになれば、あなたも立派なデータベース操作の第一歩を踏み出したことになります。