计算用户的排名

时间:2014-08-30 08:57:01

标签: php mysql sql codeigniter ranking

我想用MySQL计算排名。我有一个名为result

的表
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个等等

我尝试了像

这样的查询
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,56,42

有什么办法可以计算出用户的等级吗?

3 个答案:

答案 0 :(得分: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);

答案 1 :(得分: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

答案 2 :(得分:0)

您可以使用变量来计算表格的DenseRank,我假设这个排名会在每个 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"
  • 中的更改 如果"value"重复,则
  • @rept不会递增
  • @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(因此称为“密集”一词)并且它会在下一个“分区”重新开始。

nb:术语partition暗示在dbms系统中使用的partition by具有用于排名的分析函数(Oracle,DB2,SQL Server,PostGres,其他)

See this SQLfiddle demo