Bygg komplex SQL steg för steg.
Detta ger dig de böcker som har båda de nödvändiga taggarna. Det är bara så tillförlitligt som din tabelldefinition. Din tabelldefinition bör inte tillåta en bok att ha samma tagg två gånger. Du behöver en UNIK begränsning på (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
Du kan använda det i en 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
Att gå med på röstbordet bör ta bort book_id 6 från resultatet. (Inga röster för 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
Nu kan du lägga till röstkolumnen i frågan.
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
Slutligen kan du summera rösterna.
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
Din version fungerar inte eftersom den returnerar fel bok-id-nummer. Kombinationen av JOIN på books_votes och WHERE-satsen gör inte vad du förväntade dig att den skulle göra.
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
Bok 2 ingår inte för att den har båda taggarna, utan för att den har två röster.
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