Изградете сложен SQL стъпка по стъпка.
Това ви дава книгите, които имат и двата задължителни етикета. Толкова е надеждно, колкото и дефиницията на вашата таблица. Вашата дефиниция на таблица не трябва да позволява една книга да има един и същ етикет два пъти. Имате нужда от УНИКАЛНО ограничение за (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
Можете да го използвате в 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
Присъединяването към таблицата с гласове трябва да премахне book_id 6 от резултата. (Няма гласове за 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
Сега можете да добавите колоната за гласуване към заявката.
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
Накрая можете да сумирате гласовете.
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
Вашата версия не работи, защото връща грешни идентификационни номера на книги. Комбинацията от JOIN на books_votes и клаузата WHERE не прави това, което очаквахте.
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
Книга 2 е включена не защото има и двата етикета, а защото има два гласа.
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