Construisez du SQL complexe étape par étape.
Cela vous donne les livres qui ont les deux balises requises. C'est seulement aussi fiable que la définition de votre table. Votre définition de table ne doit pas permettre à un livre d'avoir deux fois la même balise. Vous avez besoin d'une contrainte UNIQUE sur (book_id, tag_id).
SELECT book_id
FROM books_tags
WHERE books_tags.tag_id IN (716, 101)
GROUP BY book_id
HAVING COUNT(tag_id) = 2
book_id
--
6
3
Vous pouvez l'utiliser dans un JOIN.
SELECT books.id
FROM books
INNER JOIN (
SELECT book_id
FROM books_tags
WHERE books_tags.tag_id IN (716, 101)
GROUP BY book_id
HAVING COUNT(tag_id) = 2) bt ON bt.book_id = books.id
book_id
--
6
3
Rejoindre la table des votes devrait supprimer book_id 6 du résultat. (Aucun vote pour 6.)
SELECT books.id
FROM books
INNER JOIN (
SELECT book_id
FROM books_tags
WHERE books_tags.tag_id IN (716, 101)
GROUP BY book_id
HAVING COUNT(tag_id) = 2) bt ON bt.book_id = books.id
INNER JOIN books_votes bv ON bv.book_id = books.id
book_id
--
3
Vous pouvez maintenant ajouter la colonne de vote à la requête.
SELECT books.id, bv.vote
FROM books
INNER JOIN (
SELECT book_id
FROM books_tags
WHERE books_tags.tag_id IN (716, 101)
GROUP BY book_id
HAVING COUNT(tag_id) = 2) bt ON bt.book_id = books.id
INNER JOIN books_votes bv ON bv.book_id = books.id
book_id vote
--
3 1
Enfin, vous pouvez additionner les votes.
SELECT books.id, SUM(bv.vote) AS total_votes
FROM books
INNER JOIN (
SELECT book_id
FROM books_tags
WHERE books_tags.tag_id IN (716, 101)
GROUP BY book_id
HAVING COUNT(tag_id) = 2) bt ON bt.book_id = books.id
INNER JOIN books_votes bv ON bv.book_id = books.id
GROUP BY books.id;
book_id total_votes
--
3 1
Votre version ne fonctionne pas, car elle renvoie les mauvais numéros d'identification de livre. La combinaison du JOIN sur books_votes et de la clause WHERE ne fait pas ce que vous attendiez.
SELECT books.id AS books_id
FROM books
JOIN books_votes ON books.id = books_votes.book_id
JOIN books_tags ON books.id = books_tags.book_id
WHERE books_tags.tag_id IN (716, 101)
GROUP BY books.id
books_id
--
3
2
Le livre 2 est inclus non pas parce qu'il a les deux balises, mais parce qu'il a deux votes.
SELECT books.id AS books_id, books_tags.tag_id, books_votes.vote
FROM books
JOIN books_votes ON books.id = books_votes.book_id
JOIN books_tags ON books.id = books_tags.book_id
WHERE books_tags.tag_id IN (716, 101)
ORDER BY books_id, tag_id
book_id tag_id vote
--
2 101 1
2 101 1
3 101 1
3 716 1