У меня две таблицы:
ranking_history
| user_id | ranking | time
| 1 | 2 | 2018-05-21
| 1 | 5 | 2018-04-28
| 2 | 9 | 2018-05-21
| 2 | 1 | 2018-04-28
пользователь
| id | ranking
| 1 | 7
| 2 | 3
Мне нужно присоединиться к этим двум таблицам, чтобы создать таблицу так:
| id | ranking | last_weeks_ranking | last_months_ranking
| 1 | 7 | 2 | 5
| 2 | 3 | 9 | 1
Это то, что я пробовал:
SELECT *, r1.ranking as last_weeks_ranking, r2.ranking as last_months_ranking
from user
left join ranking_history r1 on user.id = r1.user_id where r1.time = '2018-05-21'
left join ranking_history r2 on user.id = r2.user_id where r2.time = '2018-04-28'
Выход в порядке, но мне нужно присоединиться к одной таблице дважды. Есть ли более простой способ сделать это?
Использовать условную агрегацию
SELECT user.id,
MAX(user.ranking) as ranking,
MAX(CASE WHEN r1.time = '2018-05-21' THEN r1.ranking END) as last_weeks_ranking,
MAX(CASE WHEN r1.time = '2018-04-28' THEN r1.ranking END) as last_months_ranking
FROM user
JOIN ranking_history r1
ON user.id = r1.user_id
GROUP BY user.id
Другой подход заключается в использовании связанных друг с другом подзапросов:
SELECT
user.id,
user.ranking,
(SELECT
ranking_history.ranking
FROM
ranking_history
WHERE
ranking_history.user_id = user.id
AND ranking_history.time >= NOW() - INTERVAL 1 WEEK - INTERVAL 1 DAY
ORDER BY
ranking_history.time ASC
LIMIT 1) AS last_weeks_ranking,
(SELECT
ranking_history.ranking
FROM
ranking_history
WHERE
ranking_history.user_id = user.id
AND ranking_history.time >= NOW() - INTERVAL 1 MONTH - INTERVAL 1 DAY
ORDER BY
ranking_history.time ASC
LIMIT 1) AS last_months_ranking
FROM
user
PS: Я добавил динамический расчет даты для столбцов last_weeks_ranking
и last_months_ranking
вместо этого, используя фиксированные значения "2018-05-21" и "2018-04-28",
Результат
| id | ranking | last_weeks_ranking | last_months_ranking |
+----+---------+--------------------+---------------------+
| 1 | 7 | 2 | 5 |
| 2 | 3 | 9 | 1 |
см. демо http://sqlfiddle.com/#!9/2f8e2c/9
user.ranking
и вместо этого сохраняя текущий рейтинг вranking_history
.