sql >> Databasteknik >  >> RDS >> Mysql

Behöver hjälp med sql-fråga för att hitta saker taggade med alla angivna taggar

Med 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)

Använda en 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

Använder 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)

Förklaring

Kärnan i saker är att COUNT(DISTINCT t.name) måste matcha antalet taggnamn för att säkerställa att alla dessa taggar är relaterade till inlägget. Utan DISTINCT finns det en risk att dubbletter av ett av namnen kan returnera en räkning på 7 - så att du skulle få en falsk positiv.

Prestanda

De flesta kommer att säga att JOIN är optimal, men JOINs riskerar också att duplicera rader i resultatuppsättningen. FINNS skulle vara mitt nästa val - ingen dubbelrisk, och generellt snabbare utförande, men att kontrollera förklara planen kommer i slutändan att berätta vad som är bäst baserat på dina inställningar och dina data.



  1. PostgreSQL främmande nyckel existerar inte, frågan om arv?

  2. Entity Framework Code First MaxLength och FixedLegth (char vs varchar)

  3. data som laddas från SQLitE databse sparas inte i modellklassen ArrayList android

  4. java.lang.AbstractMethodError:com.mysql.jdbc.PreparedStatement.setBlob(ILjava/io/InputStream;)V