Во-первых, ваш текущий запрос не должен компилироваться, поскольку он использует p
в качестве псевдонима как для комментариев, так и для таблицы сообщений.
Во-вторых, вы присоединяетесь к votes
дважды: один раз за нет и один раз за да. Используя оператор CASE, вы можете вычислить суммы обоих значений за одно соединение. Вот пример запроса:
select
p.*,
sum(case when v.vote_type_id = 1 then 1 else 0 end) as yes,
sum(case when v.vote_type_id = 2 then 1 else 0 end) as no,
count(c.id) as comment_count
from posts p
left join votes v on v.post_id = p.id
left join comments c on c.post_id = p.id
order by yes desc
limit 0, 10
В-третьих, вы можете убедиться, что существуют правильные внешние ключи для отношений между сообщениями, голосами и комментариями. Также может помочь индекс (post_id, vote_type_id)
на votes
.