Я думаю, это то, что вы хотите:
select user_name,
sum(site_point + park_point + division_point) as points
from visits v join
users u
on u.user_id = v.user_id
group by user_name
order by points desc
limit 5;
Единая агрегация упрощает расчет.
Вы можете не осознавать этого, но union
при некоторых обстоятельствах выдаст неверные результаты. Union
удаляет дубликаты, поэтому, если у пользователя одинаковые частичные оценки, две строки становятся одной.
EDIT:
Немного сложнее получить первые 5 баллов , но возможно:
select user_name,
sum(site_point + park_point + division_point) as points
from visits v join
users u
on u.user_id = v.user_id
group by user_name
having points >= (select distinct points
from (select sum(site_point + park_point + division_point)
from visits v join
users u
on u.user_id = v.user_id
group by user_name
) vu
order by points desc
limit 1 offset 4
)
order by points desc
limit 5;
Предполагая, что user_name
является уникальным для данного идентификатора, вы можете упростить это немного:
having points >= (select distinct points
from (select sum(site_point + park_point + division_point) as points
from visits v
group by user_id
) vu
order by points desc
limit 1 offset 4
)
И, если вы хотите, чтобы кто-то соответствовал топ-5 пользователям - но возвращал более 5 строк при наличии связей - тогда измените select distinct
на select
в подзапросе.