Улучшите SQL-запрос, заменив внутренний запрос

Я пытаюсь упростить этот SQL-запрос (я заменил настоящие имена таблиц метафорическими), в первую очередь избавиться от внутреннего запроса, но у меня застыли мозги, и я не могу придумать, как это сделать.

Меня больше всего беспокоит (помимо эстетики) производительность при больших нагрузках.

Целью запроса является подсчет всех книг, сгруппированных по жанрам, найденных на какой-либо конкретной полке, где хранится книга (отсюда и внутренний запрос, который эффективно сообщает, на какой полке считать книги).

SELECT g.name, count(s.book_id) occurances FROM genre g
LEFT JOIN shelve s ON g.shelve_id=s.id
WHERE s.id=(SELECT genre_id FROM book WHERE id=111)
GROUP BY s.genre_id, g.name

person user1678312    schedule 20.10.2020    source источник
comment
Ваш запрос должен быть в порядке, хотя s.genre_id не требуется в файле GROUP BY. Я тоже не понимаю, как s.id = b.genre_id. Образцы данных и желаемые результаты прояснят, что вы хотите сделать.   -  person Gordon Linoff    schedule 20.10.2020


Ответы (1)


Кажется, вы хотите знать, что многие книги на полке относятся к тому же жанру, что и книга 111: если вам понравилась книга X, у нас есть много похожих книг в наличии.

Я заметил одну вещь: предложение WHERE в оригинале требовало значения для таблицы shelve, эффективно преобразовывая его во ВНУТРЕННЕЕ СОЕДИНЕНИЕ. И говоря о JOIN, вы можете JOIN вместо вложенного выбора.

SELECT g.name, count(s.book_id) occurances 
FROM genre g
INNER JOIN shelve s ON s.id = b.shelve_id
INNER JOIN book b on b.genre_id = s.id 
WHERE b.id=111
GROUP BY g.id, g.name

Если подумать, я мог бы также начать с book, а не с genre. В конце концов, единственная причина, по которой вам вообще нужна таблица genre, заключается в том, чтобы найти name, и поэтому сопоставление с ней по id может быть более эффективным.

SELECT g.name, count(s.book_id) occurances 
FROM book b 
INNER JOIN shelve s ON s.id = b.genre_id
INNER JOIN genre g on g.shelve_id = s.id
WHERE b.id=111
GROUP BY g.id, g.name

Не уверен, что они соответствуют вашему представлению о простоте или нет, но это альтернативы.

... если только совпадение shelve.id с book.genre_id не является опечаткой в ​​вопросе. Кажется очень странным, что две таблицы будут иметь одни и те же значения id, и в этом случае они оба будут неправильными.

person Joel Coehoorn    schedule 20.10.2020
comment
Из вопроса следует, что жанр существует на одной полке, но полка может содержать несколько жанров. У них должны быть очень большие полки... - person Nick; 20.10.2020