Самый простой способ - объединить все таблицы, сгруппировать по автору и библиотеке и подсчитать:
select b.author_id, a.name, lbr.library_id, count(*)
from book b
join book_item bi on bi.book_id = b.id
join library_book_relation lbr on lbr.book_item_id = bi.id
join author a on a.id = b.author_id
group by b.author_id, a.name, lbr.library_id
order by b.author_id, a.name, lbr.library_id;
На SQL стандарт, вам нужно только group by b.author_id, lbr.library_id
, потому что вам нужна одна строка результатов на автора и библиотека. MySQL должен уметь это делать, поэтому вы можете удалить a.name
из предложения group by. (Существует только одно имя для каждого идентификатора автора.)
Вы также можете подсчитать, прежде чем присоединиться к таблице авторов. Считается хорошим стилем агрегирование перед присоединением и может очень помочь (или даже оказаться необходимым) в более сложных запросах.
select c.author_id, a.name, c.library_id, c.books
from
(
select b.author_id, lbr.library_id, count(*) as books
from book b
join book_item bi on bi.book_id = b.id
join library_book_relation lbr on lbr.book_item_id = bi.id
group by b.author_id, lbr.library_id
) c
join author a on a.id = c.author_id
order by c.author_id, a.name, c.library_id;
Однако вышеперечисленные запросы не учитывают нули. Они просто показывают, как часто можно найти авторов в библиотеках. Вот как подсчитать, сколько книг у автора №1 в библиотеке № 123:
select a.id, a.name, coalesce(b.books, 0)
from author a
left join
(
select b.author_id, count(*) as books
from book b
join book_item bi on bi.book_id = b.id
join library_book_relation lbr on lbr.book_item_id = bi.id
where lbr.library_id = 123
group by b.author_id
) c on c.author_id = a.id
where a.id = 1;
Или с помощью подзапроса в предложении select:
select
a.id,
a.name,
(
select count(*)
from book b
join book_item bi on bi.book_id = b.id
join library_book_relation lbr on lbr.book_item_id = bi.id
where lbr.library_id = 123
and b.author_id = a.id
) as books
from author a
where a.id = 1;
Наконец, запрос на получение все авторы и все библиотеки, включая нули:
select a.id as author_id, a.name, l.id as library_id, coalesce(c.books, 0)
from author a
cross join library l
left join
(
select b.author_id, lbr.library_id, count(*) as books
from book b
join book_item bi on bi.book_id = b.id
join library_book_relation lbr on lbr.book_item_id = bi.id
group by b.author_id, lbr.library_id
) c on c.author_id = a.id and c.library_id = l.id
order by a.id, l.id;