EatSmartシステム部ブログ

ウェブサイトの開発や運営に関する情報です。

EXISTS句を使ったサブクエリについて

今回は、もぐナビのプロジェクトの実装で学んだことについてまとめていきます。 テーマは、EXISTS句を使ったSQLの振り返りです。

実装の内容

特定条件のクチコミを抽出する際に、任意のユーザーのlikeが既にある場合は 除外クチコミとしたいので、その判定にEXISTS句を使っていこうと思います。 最初にEXISTSを使わない例と比較していきます。

①EXISTS句を使わない実装

最初に実装していた方法として、任意のユーザーのlikeがあるかの判定は、countの戻り値 を利用すればいいかなと思い、以下のようなメソッドを作って処理していました。

public static boolean isOffcialVote(BigDecimal userCommentId) throws SystemException {
        int count = DBConnectionManager.getInstance().getConnection().getInt(
                "SELECT COUNT(*) " +
                "FROM t_user_comment_voting(クチコミに関するlikeがあるテーブル) t " +
                "WHERE t.user_id =  '任意のuserId' AND t.user_comment_id = ? ",
                userCommentId);
        return count > 0;
    }

trueの場合は、countが1以上ということなので、既にlikeありと見なしてlikeの対象にしない。 (つまり、falseになったものが抽出したいコメント対象になります。)
※userCommentIdというのは、クチコミに関してのユニークなIDです。

②EXISTS句を使った実装

public List<UserCommentBean> getNewComment() {
        return getResult(
                "SELECT * "+
                /*対象のコメントを抽出する(期間やユーザーの属性などの条件がある)*/
                ") AS w " +
                "WHERE NOT EXISTS (SELECT t.user_comment_id from t_user_comment_voting t " +
         "WHERE t.user_comment_id = w.user_comment_id AND t.user_id = '任意のuserId' ) ",
                UserCommentBean.class);
    }

この例では、対象となるコメントを抜き出す時に、サブクエリでNOT EXISTSを使っています。そうすると、得られる結果は既に任意のユーザーのlikeが除外されたものになります。

EXISTS句を使うことのメリット

上記の例だと、わざわざ①のメソッドのような判定を入れる必要がなくなります。 実行効率の観点でも、また、COUNT関数を使うよりメリットがあります。EXISTS句を利用した場合、 1行でも該当の行が見つかった場合にtrueを返すのでそこでスキャンが終わります。 COUNTの場合、1行見つかった後も検索が走るので、existsに比べて処理が遅くなるようです。

さらに、別の場面でも使う機会があったので、参考までに記載しておきます。
もぐナビで配信しているニュースで、スイーツのタグ(カテゴリを指す)がついたものだけを取得する。

SELECT vbi.title
FROM v_blog_item vbi
WHERE vbi.del_kbn = '01'
AND EXISTS (
SELECT vbit.guid
FROM v_blog_item_tag vbit
WHERE vbit.guid = vbi.guid
AND vbit.tag = 'スイーツ'
) 
ORDER BY vbi.pub_date DESC
LIMIT 10;

---------------------------------------------------------------------------------------------------
結果
スイーツランキング発表!アイス、チョコ、プリンなどお気に入りスイーツの1位とは?
今週のファミリーマート新商品6選☆クリーミーな物からヘルシーな物までご紹介!
今週のローソン新商品6選!桜スイーツからチョコたっぷりスイーツが登場♪
今週のセブン新商品6選!和洋スイーツから菓子パンなど♪
【最強のおやつ】『まるごとバナナ』がさらに美味しくなってる!
今週のローソン新商品6選!チョコづくしのバレンタイン週間♪
ブルボン「ルマンドアイス抹茶」ほろ苦さにホワイトチョコのミルク感♪
ファミマ「たべる牧場チョコ」新発売!優しい甘さの濃厚テイスト♪
コメダ×ゴディバ「シロノワール」など新発売!カカオ香る贅沢なチョコソフトに♪
ロッテ「爽 抹茶フロマージュ」新発売!ひと口食べればリフレッシュ♪

まとめ

以上、簡単ではありますが知っていると使える場面があるし、EXISTSにとどまらずサブクエリを さくさく書いていけると、ほしいデータがすぐ手に入るので今後も勉強を続けていきたいと思いました。