I'm trying to simplify this SQL query (I replaced real table names with metaphorical), primarily get rid of the inner query, but I'm brain frozen can't think of any way to do it.
My major concern (aside from aesthetics) is performance under heavy loads
The purpose of the query is to count all books grouping by genre found on any particular shelve where the book is kept (hence the inner query which is effectively telling which shelve to count books on).
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
It seems like you want to know many books that are on a shelf are in the same genre as book 111: if you liked book "X", we have this many similar books in stock.
One thing I noticed is the
WHERE
clause in the original required a value for theshelve
table, effectively converting it to an INNER JOIN. And speaking of JOINs, you can JOIN instead of the nested select.Thinking about it more, I might also start with
book
rather thangenre
. In the end, the only reason you need thegenre
table at all is to find thename
, and therefore matching to it byid
may be more effective.Not sure they meet your idea of "simpler" or not, but they are alternatives.
... unless matching
shelve.id
withbook.genre_id
is a typo in the question. It seems very odd the two tables would share the sameid
values, in which case these will both be wrong.