Как правило, желательно, чтобы логика соединения была частью предложения [Inner|Left] Join
, а не частью предложения Where
. В случае упрощения запроса это очищает предложение Where, так что обработчик запросов не применяет условия фильтра слишком рано, что ограничивает то, что вы хотите делать в более сложных частях запроса (и влияет на общую производительность запрос).
Путем рефакторинга условий соединения мы можем сократить запрос до его основного соединения по трем таблицам, а затем добавить соединение в специализированный подзапрос, где происходит агрегация. В результате получается только один вложенный запрос, объединяющий наименьшее количество необходимых таблиц.
Вот что я придумал:
SELECT
u.user_id
,pg.game_id
,u.user
,g.game
,g.game_cat
,ga.cat_count
,ga.fps_count
FROM users u
inner join played_games pg
on u.user_id = pg.user_id
inner join games g
on pg.game_id = g.id
inner join
(
select
ipg.user_id
,ig.game_cat
,count(ig.game) cat_count
,sum(case when ig.game_cat = 'fps' then 1 else 0 end) fps_count
from played_games ipg
inner join games ig
on ipg.game_id = ig.id
group by
ipg.user_id
,ig.game_cat
) ga
on g.game_cat = ga.game_cat
and pg.user_id = ga.user_id
order by
ga.fps_count desc
,u.user
,ga.cat_count desc;
Одно отличие между исходным запросом (кроме небольшого переименования) состоит в том, что поле fps_count имеет значение 0 вместо NULL для игроков, которые не играли ни в одну игру FPS. Надеюсь, это не так критично, но скорее поможет добавить смысл в запрос.
Наконец, я не уверен в контексте того, как это будет использоваться. По моему мнению, он, вероятно, пытается сделать слишком много, перечисляя каждую игру, в которую играет каждый пользователь (одна цель), и суммируя категории игр, в которые играет каждый пользователь (отдельная цель). Это означает, что сводные данные повторяются многократно, например, для пользователей, играющих в несколько игр определенной категории, что не может быть идеальным. Я бы рекомендовал разделить их на два отдельных запроса, хотя я не знаю, будет ли это соответствовать вашим конкретным потребностям.
Надеюсь, это поможет.