Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Benötigen Sie Hilfe bei der SQL-Abfrage, um Dinge zu finden, die mit allen angegebenen Tags gekennzeichnet sind

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

Einen JOIN verwenden

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

Verwendung von EXISTEN

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)

Erklärung

Der springende Punkt ist, dass COUNT(DISTINCT t.name) muss mit der Anzahl der Tag-Namen übereinstimmen, um sicherzustellen, dass alle diese Tags mit dem Beitrag in Verbindung stehen. Ohne DISTINCT besteht die Gefahr, dass Duplikate eines der Namen eine Zählung von 7 zurückgeben könnten – Sie hätten also ein falsch positives Ergebnis.

Leistung

Die meisten werden Ihnen sagen, dass der JOIN optimal ist, aber JOINs riskieren auch, Zeilen in der Ergebnismenge zu duplizieren. EXISTS wäre meine nächste Wahl – kein doppeltes Risiko und im Allgemeinen schnellere Ausführung, aber die Überprüfung des Erklärungsplans wird Ihnen letztendlich sagen, was basierend auf Ihrer Einrichtung und Ihren Daten am besten ist.