🕌

SQLのWHERE EXISTSの使いところを復習する

に公開

はじめに

業務でSQLのコードを見ていると、しばしばWHERE EXISTSという構文を見かけます。
対象のサブクエリの結果が真の場合にメインのクエリの結果に追加していくものですが、JOINしてからWHEREで絞りこむのではダメなのでしょうか?
実行結果がよく似た二つの構文ですが、どういう場合に使い分けるのでしょうか?
調べなおしてみました。

JOINだとまずいこと

実はパフォーマンスを求められないのであればWHERE EXISTSはJOINで全てカバーできるようです。
そうすると、じゃあ全部JOINで良くない?って思いますよね。
JOINの方が結果を予想しやすいし書き方も簡単に感じます。

では、なぜ全部JOINだとだめなのか。

・絞り込み条件が複雑な場合はEXISTSの方が簡潔になる。
・JOINだとWHERE句の絞り込みに重複データがあると扱いずらい。
・NOT EXISTSを使う場合はJOINに置き換えるのは大変になる。

といったケースがあるようです。

具体例

JOINの場合
            
                SELECT
                    r.name
                FROM
                    users u
                    INNER JOIN
                        roles r ON u.role_id = r.role_id
                WHERE
                    u.deleted_at IS NULL
                    AND r.name = 'admin'
                    AND u.user_id = :user_id
            ;
EXISTSの場合
            SELECT
                name
            FROM
                users
            WHERE
                users.deleted_at IS NULL
                AND EXISTS (
                    SELECT
                        users.role_id
                    FROM
                        roles
                    WHERE
                        users.role_id = roles.role_id
                        AND name = 'admin'
                )
                AND user_id = :user_id

上記はどちらも同じ結果になります。
取得したい情報の主体や、読みやすさも選ぶ基準になりそうです。
また、EXISTSの場合は連結しているときと違って、SELECT文のnameが曖昧エラーにならないこともありますね。

おわりに

よく見かける割には、違いのわかりにくい両者ですが、なんとなく掴めてきたでしょうか?
筆者自身、どちらを使うか結構迷うのですが、雰囲気が伝われば幸いです。

株式会社ONE WEDGE

【Serverlessで世の中をもっと楽しく】 ONE WEDGEはServerlessシステム開発を中核技術としてWeb系システム開発、AWS/GCPを利用した業務システム・サービス開発、PWAを用いたモバイル開発、Alexaスキル開発など、元気と技術力を武器にお客様に真摯に向き合う価値創造企業です。
https://onewedge.co.jp

Discussion