@VoRoN1999

Как правильно написать запрос к БД?

Добрый день.
Есть 3 таблицы:

1) users
-id

2) achievements
-user_id (привязан к id таблицы users может иметь несколько записей с одинаковым значением)
-coefficient_1
-coefficient_2
-coefficient_3

3) coefficient
- id (привязан к coefficient_1, coefficient_2, coefficient_3 таблицы achievements)
- coefficient (число)

Мне нужно получить первых 5 пользователей с наибольшим произведением всех coefficient, сложенных между собой.

Пример:

1) users
-id (1)
-id (2)
-id (3)

2) achievements
-user_id (1)
-coefficient_1 (1)
-coefficient_2 (1)
-coefficient_3 (3)

-user_id (1)
-coefficient_1 (2)
-coefficient_2 (2)
-coefficient_3 (3)

-user_id (2)
-coefficient_1 (1)
-coefficient_2 (2)
-coefficient_3 (3)

3) coefficient
- id (1)
- coefficient (0,5)

- id (2)
- coefficient (1)

- id (3)
- coefficient (5)

Мы получаем всех пользователей, затем нужно получить все записи из таблицы achievements для каждого пользователя и посчитать произведение всех коэффициентов (формула coefficient_1 * coefficient_2 * coefficient_3), разумеется умножаем не на id, а на значение из таблицы coefficient. Таким образом мы получаем:

Пользователь с id 1 - лучший, т.к. ему принадлежат 2 записи в таблице achievements, сумма этих двух записей составляет:
2) achievements
-user_id (1)
-coefficient_1 (1) - 0,5
-coefficient_2 (1) - 0,5
-coefficient_3 (3) - 5
-- Произведение = 1.25

-user_id (1)
-coefficient_1 (2) -1
-coefficient_2 (2) -1
-coefficient_3 (3) - 5
-- Произведение = 5

--- Сумма 1.25 + 5 = 6.25

Так нужно пересчитать всех пользователей и выявить 5 лучших.

Нужно обратить внимание на:

-- Пользователей может быть больше 15 000
-- У каждого пользователя может быть более 500 записей из таблицы achievements.

Возможно это не получится уместить в 1 SQL запрос. Нужен самый оптимальный вариант для решения этой задачи.
Если что-то не понято, то задавайте вопросы.
Спасибо!
  • Вопрос задан
  • 51 просмотр
Решения вопроса 1
@AndryG
Если я правильно понял вот это все нагромождение id :)

select 
 a.userId,
 sum(k1.val * k2.val * k3.val) points 
from aciv a
 join users on u.userId = a.userId  -- эта строка вроде как и не нужна, если нут других ограничений по users
 join kof k1 on a.kof1 = k1.id
 join kof k2 on a.kof2 = k2.id
 join kof k3 on a.kof3 = k3.id
group by a.userId
order by 2 desc
limit 5


Запрос будет тяжелый, ибо без пересчета всех данных нужные не определить.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы