2014-08-30 3 views
0

Я хочу рассчитать ранг, используя MySQL. У меня есть таблица под названием результатвычислить ранг пользователя

result_id test_id exam_id user_id percentage 
    1   5   6   50   57 
    2   5   6   58   76 
    3   5   6   65   42 

Я хочу, чтобы вычислить ранг пользователя в соответствии с его user_id и test_id как user_id (58) имеет 1 ранг user_id (50) имеет 2 и так далее

I пытался запрос как

select percentage from result where test_id=$test_id(i.e 5) and user_id=$user_id(i.e 58) 

но это дает 76 и не дает ранг

Я также попытался

select percentage from result where test_id=$test_id(i.e 5) 

, но это дает мне 57,76,42

Есть ли способ, с помощью которого я могу вычислить ранг пользователя?

ответ

0

Вы можете просто использовать ORDER BY percentage DESC. Попробуйте это ...

$con = mysqli_connect("host","user","password","db_name"); 
if (mysqli_connect_errno()){ 
    echo "Failed to connect to MySQL: " . mysqli_connect_error(); 
} 
$sql = 'SELECT * FROM result ORDER BY percentage DESC'; 
$result = mysqli_query($con, $sql); 
if (!mysqli_query($con, $sql)) { 
    die('Error: '. mysqli_error($con)); 
} 
$i = 1; 
while($row = mysqli_fetch_array($result)) { 
    echo 'User ID ' . $row['user_id'] . ' has rank ' . $i . ' and percentage ' . $row['percentage'] . '</br>'; 
    $i++; 
} 
mysql_close($con); 
0

Вы можете сделать это в MySQL без возврата всех результатов. Для одного пользователя:

select percentage 
     (select count(*) 
     from result r2 
     where test_id = r.test_id and r2.percentage > r.percentage 
     ) + 1 as rank 
from result r 
where test_id=$test_id(i.e 5) and user_id=$user_id(i.e 58 
0

Вы можете использовать переменные для расчета DENSERANK за ​​столом, я предположил, что этот рейтинг будет вновь начать с 1 для каждого комбинации test_id и exam_id которой я отношусь как "partition" полей, и для этого запроса "value" мы будем использовать для определения ранга - процент (в порядке убывания); поэтому самый высокий процент получает ранг 1

так:

set @patn = ''; 
set @rank = 1; 
set @valu = ''; 
set @rept = 1; 

SELECT test_id 
     , exam_id 
     , user_id 
     , percentage 
     , DenseRank 
FROM (
     SELECT test_id 
      , exam_id 
      , user_id 
      , percentage 
      , @rank := if(@patn=grp, if(@valu=percentage, @rank, @rank + @rept),1) as DenseRank 
      , @rept := if(@patn=grp, if(@valu=percentage, @rept, 1),1) 
      , @patn := grp 
      , @valu := percentage  
     FROM (
      select 
         concat(test_id,exam_id) AS grp 
        , test_id 
        , exam_id 
        , user_id 
        , percentage 
       from results 
       order by 
         test_id 
        , exam_id 
        , percentage DESC 
      ) dta 
    ) dtb; 
  • @patn отслеживает изменения в "partition"
  • @rept отслеживает изменения в "value" колонке
  • @rept не делает приращение, если "value" повторений
  • @rank - расчетный плотный ранг

Внутренний запрос (DTA) должны быть отсортированы по:

  • в "partition" колонн, например, test_id, exam_id
  • и столбец "value", например.Процент

Следующий уровень внешнего запроса (DTB),

  • сравнивать текущую строку "partition" с предыдущей строки "partition"
  • если "partition" изменений, то ранг = 1
  • еще сравнить предыдущую строку "value" с текущим рядом "value"
  • если "value" изменяется, то увеличение ранга на 1
  • еще присвоить тот же рейтинг
  • текущий "partition" сохранен; считается предыдущим "partition" в следующей строке
  • текущий "value" сохранен; следует рассматривать предыдущий "value" на следующей строке

Наконец:

  • необходимые столбцы выбраны

Расширение выборочные данные немного это результат:

| TEST_ID | EXAM_ID | USER_ID | PERCENTAGE | DENSERANK | 
|---------|---------|---------|------------|-----------| 
|  5 |  6 |  580 |   76 |   1 | 
|  5 |  6 |  50 |   57 |   2 | 
|  5 |  6 |  581 |   57 |   2 | 
|  5 |  6 |  582 |   57 |   2 | 
|  5 |  6 |  583 |   42 |   3 | 
|  5 |  6 |  65 |   42 |   3 | 

|  6 |  6 |  580 |   76 |   1 | 

Где расчет ранжирования должен только шаг вверх на 1 (отсюда и термин «плотный»), и он возобновляется на одном для следующего «раздела».

нб: термин partition намекает на partition by, используемые в системе СУБД, которые действительно имеют аналитические функции для ранжирования (Oracle, DB2, SQL Server, Postgres, другие)

See this SQLfiddle demo

Смежные вопросы