sql >> Database >  >> RDS >> Mysql

Selecteer in een veel-op-veel-relatie in MySQL

Er zijn twee manieren om dit te doen. Ik geef de voorkeur aan de eerste manier, namelijk om voor elke tag zelf lid te worden:

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 = ?;

De andere manier werkt ook, maar met GROUP BY in MySQL heeft de neiging om een ​​tijdelijke tabel op te lopen en de prestaties zijn traag:

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;

Re reactie van @Erikoenig:

Als u er zeker van wilt zijn dat er geen extra tags zijn, kunt u dit op deze manier doen:

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;

Door de WHERE-component te verwijderen, kunnen andere tags worden geteld, als die er zijn. Dus COUNT() kan groter zijn dan 3.

Of als het aantal precies drie tags is, maar sommige van deze drie zijn niet de juiste tags, dan zorgt de SUM()-voorwaarde in de HAVING-component ervoor dat alle drie de tags die u wilt aanwezig zijn in de groep.



  1. Hoe een ADDM-taak te maken en het rapport ervan te controleren

  2. nieuwe SQL-record-ID ophalen

  3. Laravel-migratie - schending van integriteitsbeperking:1452 Kan een onderliggende rij niet toevoegen of bijwerken:een externe-sleutelbeperking mislukt

  4. SQLSTATE[23000]:schending van integriteitsbeperking met geldige beperking