Положение:
Таблица книга связана с одним или несколькими авторами через таблицу _author_book . также связано с одним или несколькими жанрами через таблицу _book_genre .
При выборе всех книг, всех их жанров и всех их авторов возвращается количество строк (предположим, что каждая книга имеет по крайней мере один жанр и автора):
- ПРОБЛЕМА:
books.map (| book | book.genres.size * book.authors.size) .sum
что я хочу это:
- DESIRED:
books.map (| book | [book.genres.size, book.authors.size] .max) .sum
так, учитывая 10 книг, каждая книга имеет 5 жанров и 4 автора:
- ПРОБЛЕМА: возвращено 200 строк (5 * 4 * 10)
- DESIRED: возвращено 50 строк ([5,4] .max * 10)
Пример данных:
mysql> SELECT * FROM book
id | title
----+---------------------------
1 | Dune: The Butlerian Jihad
2 | The Talisman
mysql> SELECT * FROM genre
id | title
----+-------------
1 | Military
2 | Horror
3 | Thriller
4 | Sci-Fi
5 | Fiction
6 | Speculative
mysql> SELECT * FROM author
id | title
----+------------------
1 | Brian Herbert
2 | Kevin J Anderson
3 | Stephen King
4 | Peter Straub
mysql> SELECT * FROM _author_book
book_id | author_id
---------+-----------
1 | 1
1 | 2
2 | 3
2 | 4
mysql> SELECT * FROM _book_genre
book_id | genre_id
---------+-----------
1 | 1
1 | 4
1 | 5
1 | 6
2 | 2
2 | 3
2 | 5
Вот что не так:
mysql> SELECT book.id AS "book.id", ..., author.fullname AS "author.fullname" FROM book
-> LEFT JOIN _book_genre ON book.id = _book_genre.book_id
-> LEFT JOIN genre ON genre.id = _book_genre.genre_id
-> LEFT JOIN _author_book ON book.id = _author_book.book_id
-> LEFT JOIN author ON author.id = _author_book.author_id;
book.id | book.title | genre.id | genre.name | author.id | author.fullname
---------+------------+----------+-------------+-----------+------------------
1 | Dune: The… | 1 | Military | 1 | Brian Herbert
1 | Dune: The… | 4 | Sci-Fi | 1 | Brian Herbert
1 | Dune: The… | 5 | Fiction | 1 | Brian Herbert
1 | Dune: The… | 6 | Speculative | 1 | Brian Herbert
---------+------------+----------+-------------+-----------+------------------
1 | Dune: The… | 1 | Military | 2 | Kevin J Anderson
1 | Dune: The… | 4 | Sci-Fi | 2 | Kevin J Anderson
1 | Dune: The… | 5 | Fiction | 2 | Kevin J Anderson
1 | Dune: The… | 6 | Speculative | 2 | Kevin J Anderson
---------+------------+----------+-------------+-----------+------------------
2 | The Talis… | 2 | Horror | 3 | Stephen King
2 | The Talis… | 3 | Thriller | 3 | Stephen King
2 | The Talis… | 5 | Fiction | 3 | Stephen King
---------+------------+----------+-------------+-----------+------------------
2 | The Talis… | 2 | Horror | 4 | Peter Straub
2 | The Talis… | 3 | Thriller | 4 | Peter Straub
2 | The Talis… | 5 | Fiction | 4 | Peter Straub
Надеюсь, понятно, в чем проблема. Результат первого объединения в жанре / _book_genre объединяется со всеми результатами автора, в результате получается набор из 14 строк, тогда как на самом деле достаточно набора результатов, состоящего только из семи строк:
book.id | book.title | genre.id | genre.name | author.id | author.fullname
---------+------------+----------+-------------+-----------+------------------
1 | Dune: The… | 1 | Military | 1 | Brian Herbert
1 | Dune: The… | 4 | Sci-Fi | 2 | Kevin J Anderson
1 | Dune: The… | 5 | Fiction | 1 | Brian Herbert
1 | Dune: The… | 6 | Speculative | 2 | Kevin J Anderson
---------+------------+----------+-------------+-----------+------------------
2 | The Talis… | 2 | Horror | 3 | Stephen King
2 | The Talis… | 3 | Thriller | 4 | Peter Straub
2 | The Talis… | 5 | Fiction | 3 | Stephen King
(альтернативно, дублирующиеся авторы могут иметь значения NULL, но если есть ответ, я предполагаю, что это приведет к повторению авторов, как указано выше).
Мой вопрос: существует ли какая-либо комбинация ВЫБЕРИТЕ СТАРТ ВЛЕВО, ВПРАВО, ВНУТРЕННИЙ, ВНЕШНИЙ, А-Б-А-Б, которая не позволит многим-многим результатам умножить количество строк?