sql >> データベース >  >> RDS >> Mysql

指定されたすべてのタグでタグ付けされたものを見つけるためにSQLクエリのヘルプが必要

    INの使用:

    SELECT p.*
      FROM POSTS p
     WHERE p.id IN (SELECT tg.post_id
                      FROM TAGGINGS tg
                      JOIN TAGS t ON t.id = tg.tag_id
                     WHERE t.name IN ('Cheese','Wine','Paris','Frace','City','Scenic','Art')
                  GROUP BY tg.post_id
                    HAVING COUNT(DISTINCT t.name) = 7)
    

    JOINの使用

    SELECT p.*
      FROM POSTS p
      JOIN (SELECT tg.post_id
              FROM TAGGINGS tg
              JOIN TAGS t ON t.id = tg.tag_id
             WHERE t.name IN ('Cheese','Wine','Paris','Frace','City','Scenic','Art')
          GROUP BY tg.post_id
            HAVING COUNT(DISTINCT t.name) = 7) x ON x.post_id = p.id
    

    EXISTSの使用

    SELECT p.*
      FROM POSTS p
     WHERE EXISTS (SELECT NULL
                     FROM TAGGINGS tg
                     JOIN TAGS t ON t.id = tg.tag_id
                    WHERE t.name IN ('Cheese','Wine','Paris','Frace','City','Scenic','Art')
                      AND tg.post_id = p.id
                 GROUP BY tg.post_id
                   HAVING COUNT(DISTINCT t.name) = 7)
    

    説明

    重要なのは、COUNT(DISTINCT t.name) これらすべてのタグが投稿に関連していることを確認するには、タグ名の数と一致させる必要があります。 DISTINCTがないと、名前の1つが重複すると、カウントが7になる可能性があるため、誤検知が発生する可能性があります。

    パフォーマンス

    ほとんどの場合、JOINが最適であると言われますが、JOINは結果セットの行を複製するリスクもあります。 EXISTSが私の次の選択肢です。重複するリスクはなく、一般的に実行は高速ですが、Explain Planを確認することで、最終的にはセットアップとデータに基づいて何が最善かがわかります。



    1. PostgreSQLのJSONデータ型のサイズ制限

    2. SQLServerのOracle外部テーブルに相当します

    3. MyBatisRowBoundsはクエリ結果を制限しません

    4. アップサートのバージョンの選択/挿入:高い同時実行性のデザインパターンはありますか?