sql >> Database teknologi >  >> RDS >> Mysql

Vælg i et mange-til-mange forhold i MySQL

Der er to måder at gøre dette på. Jeg foretrækker den første måde, som er at deltage selv for hvert tag:

SELECT l.*
FROM Locations l
JOIN LocationsTagsAssoc a1 ON a1.LocationID = l.ID
JOIN Tags t1 ON a1.TagID = t1.ID AND t1.Name = ?
JOIN LocationsTagsAssoc a2 ON a2.LocationID = l.ID
JOIN Tags t2 ON a2.TagID = t2.ID AND t2.Name = ?
JOIN LocationsTagsAssoc a3 ON a3.LocationID = l.ID
JOIN Tags t3 ON a3.TagID = t3.ID AND t3.Name = ?;

Den anden måde fungerer også, men ved at bruge GROUP BY i MySQL har en tendens til at pådrage sig en midlertidig tabel, og ydeevnen er langsom:

SELECT l.*
FROM Locations l
JOIN LocationsTagsAssoc a ON a.LocationID = l.ID
JOIN Tags t ON a.TagID = t.ID
WHERE t.Name IN (?, ?, ?)
GROUP BY l.ID
HAVING COUNT(*) = 3;

Rekommentar fra @Erikoenig:

Hvis du vil sikre dig, at der ikke er ekstra tags, kan du gøre det på denne måde:

SELECT l.*
FROM Locations l
JOIN LocationsTagsAssoc a ON a.LocationID = l.ID
JOIN Tags t ON a.TagID = t.ID
GROUP BY l.ID
HAVING COUNT(*) = 3 AND SUM(t.Name IN (?, ?, ?)) = 3;

Ved at fjerne WHERE-sætningen kan andre tags tælles, hvis der er nogen. Så COUNT() kan være større end 3.

Eller hvis antallet er præcis tre tags, men nogle af disse tre ikke er de rigtige tags, så sørger SUM()-betingelsen i HAVING-sætningen for, at alle tre tags, du ønsker, er til stede i gruppen.



  1. Brug af SQL Server som en DB-kø med flere klienter

  2. Logcat siger ugyldige kolonnedata1

  3. MySQL - eksploder/opdel input til lagret procedure

  4. mysql root adgangskode glemt