Добавить рейтинг столбца по выбранной группе результатов - PullRequest
0 голосов
/ 12 июня 2018

У меня есть таблица с именем myTable, в которой содержится список участников и их оценки в каждом тесте.

-----------------------------------------
id_test     id_paticipant   score
-----------------------------------------
id_test1    Partcipant1      100
id_test1    Partcipant2      200
id_test1    Partcipant3      150
id_test1    Partcipant4      300
id_test2    Partcipant1      500
id_test2    Partcipant3      250
id_test3    Partcipant2       70
id_test3    Partcipant3      150
id_test3    Partcipant4      420
id_test4    Partcipant1      120
id_test4    Partcipant2      200

Я хочу получить запрос, позволяющий мне получить ранговый столбец, в котором я буду иметьранг каждого участника в каждом тесте, как в таблице ниже.

-----------------------------------------------
id_test     id_paticipant   score   rank
-------------------------------------------------------
id_test1    Partcipant1      100    4
id_test1    Partcipant2      200    2
id_test1    Partcipant3      150    3
id_test1    Partcipant4      300    1
id_test2    Partcipant1      500    1
id_test2    Partcipant3      250    2
id_test3    Partcipant2       70    3
id_test3    Partcipant3      150    2
id_test3    Partcipant4      420    1
id_test4    Partcipant1      120    2
id_test4    Partcipant2      200    1
---------------------------------------------

я пробовал это:

SET @prev_id_test := 0;
SET @curRow := 1;
select t2.id_test, t2.id_partcipant, t2.score
,if(t2.id_test=@prev_id_test, @curRow := @curRow + 1, @curRow := 1) AS rank, @prev_id_test := t2.id_test 
from (select myTable.* from myTable order by myTable.id_test, myTable.score desc) as t2 
order by t2.id_test, t2.score, t2.id_partcipant desc;

Но это не работает, у меня ранг в порядке убыванияЯ имею в виду, что наименьшее количество баллов имеет ранг 1 и т. Д., Например:

-----------------------------------------------
id_test     id_paticipant   score   rank
-----------------------------------------------
id_test1    Partcipant1      100    1
id_test1    Partcipant2      200    3
id_test1    Partcipant3      150    2
id_test1    Partcipant4      300    4
id_test2    Partcipant1      500    2
id_test2    Partcipant3      250    1
id_test3    Partcipant2       70    1
id_test3    Partcipant3      150    2
id_test3    Partcipant4      420    3
id_test4    Partcipant1      120    1
id_test4    Partcipant2      200    2
---------------------------------------------

Может кто-нибудь помочь, пожалуйста?

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 12 июня 2018

Теперь я хочу добавить 3 других столбца:

  • Макс, который содержит максимальный балл каждой группы,
  • Мин, который содержит минимальный балл каждой группы,
  • и среднее значение, которое содержит средний балл каждой группы

Как показано в следующей таблице:

------------------------------------------------------------------------
id_test     id_participant  score   rank    Max   Min   average
------------------------------------------------------------------------
id_test1    Partcipant1      100     4      300   100    187.5
id_test1    Partcipant2      200     2      300   100    187.5
id_test1    Partcipant3      150     3      300   100    187.5
id_test1    Partcipant4      300     1      300   100    187.5
id_test2    Partcipant1      500     1      500   250    375
id_test2    Partcipant3      250     2      500   250    375
id_test3    Partcipant2       70     3      420    70    213.33
id_test3    Partcipant3      150     2      420    70    213.33
id_test3    Partcipant4      420     1      420    70    213.33
id_test4    Partcipant1      120     2      200   120    160
id_test4    Partcipant2      200     1      200   120    160
------------------------------------------------------------------------

Я пробую это:

select  
    t.*,
    (@rn := if(@it = t.id_test, @rn + 1,if(@it := t.id_test, 1, 1))) as rank,
    (select max(t1.score) from myTables t1 group by t1.id_test) as Max,
    (select min(t1.score) from myTables t1 group by t1.id_test) as Max,
    (select round((sum(t1.score)/count(t1.id_participant)), 2) from myTables t1 group by t1.id_test) as average
from
    (select t.* 
     from myTables 
     order by t.id_test, t.score desc) as t 
cross join 
    (select @it := -1, @rn := 0) params;

Но я получаю эту ошибку:

Не удается открыть таблицу

Я думаю, что это связано с тем, что таблица myTable является временной таблицей.

У вас есть идеи?

Спасибо

0 голосов
/ 12 июня 2018

Попробуйте эту версию:

select t.*,
       (@rn := if(@it = t.id_test, @rn + 1,
                  if(@it := t.id_test, 1, 1)
                 )
       ) as rank
from (select t.*
      from myTables t
      order by id_test, score desc
     ) t cross join
     (select @it := -1, @rn := 0) params;

В чем разница?Ваша версия присваивает переменные и ссылается на них в разных выражениях.MySQL (или любая другая база данных) гарантирует порядок вычисления выражений в SELECT.Итак, вы не знаете, что произойдет первым.

И, наконец, MySQL v8 + делает ненужным использование переменных.Он присоединился к остальной части сообщества SQL в поддержке оконных функций.Это упрощает логику до:

row_number() over (partition by test_id order by score_desc) as ranking
...