Уменьшить количество объединений на одном столе - PullRequest
0 голосов
/ 28 мая 2018

У меня есть две таблицы:

rating_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

user

| 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' 

Вывод в порядке, но мне нужно дважды присоединиться к одной таблице.Есть ли более простой способ сделать это?

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

Другой подход - использование связанных подзапросов:

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

0 голосов
/ 28 мая 2018

Использовать условное агрегирование

  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
...