【问题标题】:Mysql Sql statement to Get Position of Student Ranked in order of marks scoredMysql Sql语句获取学生的位置以得分的顺序排名
【发布时间】:2013-05-08 17:59:39
【问题描述】:

我需要一个 sql 来给出学生在特定考试类型中得分的顺序排列的位置,例如猫! only。下面的sql给出了学生的位置但不区分examtyp。它排名不考虑examtyp。

res_id admNo stream examtyp termId  marks   grade   points  year
   1    2129    0   CAT1      1     525       C      62     2013
   2    4093    0   CAT1      1     569       B+     69     2013
   3    2129    0   CAT2      1     550       B+     67     2013
   4    4093    0   CAT2      1     556       B+     68     2013
   6    2129    0   FINAL     1     559       B+     68     2013
   7    2129    0   AVERAGE   1     545       B      66     2013
   7    4093    0   FINAL     1     581       B+     70     2013
   8    4093    0   AVERAGE   1     569       B+     69     2013




$sql = "SELECT 1 + (SELECT count(*) FROM $table a 
        WHERE a.total_marks > b.total_marks ) AS rank 
        FROM $table b WHERE admNo=? AND examCategory=? AND termId=? AND year=?  
        ORDER BY rank LIMIT 1";
$res = $this->db->query($sql, array($admNo, $examCategory, $term, $year));

【问题讨论】:

  • 你没试过吗?如果是,请发布一些代码。
  • 欢迎来到 StackOverflow!提供您的表定义、示例数据和所需的输出以及到目前为止您自己的成果,以便我们可以看到您的努力,而不会猜测您真正希望我们帮助您的是什么与。
  • 创建一个fiddle,这样你就可以自己玩了。

标签: mysql sql


【解决方案1】:

这应该适合你:

SELECT  res_ID,
        admNo,
        stream,
        examtyp,
        termId,
        grade,
        points,
        `year`,
        Position
FROM    (   SELECT  @r:= CASE WHEN @e = examtyp THEN @r + CASE WHEN @p = points THEN 0 ELSE @i END ELSE 1 END Position,
                    @i:= CASE WHEN @p = points THEN @i + 1 ELSE 1 END incr,
                    @e:= Examtyp,
                    @p:= points,
                    res_ID,
                    admNo,
                    stream,
                    examtyp,
                    termId,
                    grade,
                    points,
                    `year`
            FROM    T,
                    (SELECT @e:= '') e,
                    (SELECT @r:= 0) r,
                    (SELECT @p:= 0) p,
                    (SELECT @i:= 0) i
            ORDER BY examtyp, points
        ) T
WHERE   T.admNo = 4093
AND     T.Examtyp = 'CAT1'

它使用与建议的使用变量相同的原理,但也按examtyp分区,每次新的考试类型将位置重置为0,它还记录以前的点来处理平局,所以如果3人获得相同的分数,他们都获得相同的位置。

Example on SQL Fiddle

请注意,在小提琴的底部窗格中,AVERAGE 的结果是相等的,因此两者都得到 position = 1

【讨论】:

    【解决方案2】:

    试试Query

    SET @rank=0;
    select
    @rank := @rank+1 AS rank 
    result_id,
    marks_scored,
    admNo,
    Aggregate_points,
    year
    from tale_name
    order by marks_scored DESC
    

    【讨论】:

    • function rank_senior($results_table, $array) { $this->db->select()->from($results_table)->where($array)->order_by('aggregate_points', 'DESC'); $query = $this->db->get(); if ($query->num_rows() > 0) { return $query->result(); } 否则 { 返回错误; }}这是我使用的查询,但我想要一个 sql,它可以在我需要的任何时候给我学生的位置,而不必在浏览器上显示排名结果
    • @user2224459 请编辑您的问题。
    • 我已经编辑了问题,表中有示例数据,我希望提供的 sql 对学生进行排名,但不区分考试类型,例如CAT1。我需要根据仅在 CAT1 或其他考试类型中得分的分数进行排名的 sql。谢谢大家
    【解决方案3】:

    试试这个查询

    查询 1

    select 
    @rn:=if(@prv=examtyp, @rn+1, 1) as rId, 
    admNo,
    @prv:=examtyp as exmtyp,
    marks
    from table1
    join
    (select @rn:=0,@prv:='') tmp
    order by exmtyp, marks desc
    

    SQL FIDDLE

    | RID | ADMNO |  EXMTYP | MARKS |
    ---------------------------------
    |   1 |  4093 | AVERAGE |   569 |
    |   2 |  2129 | AVERAGE |   545 |
    |   1 |  4093 |    CAT1 |   569 |
    |   2 |  2129 |    CAT1 |   525 |
    |   1 |  4093 |    CAT2 |   556 |
    |   2 |  2129 |    CAT2 |   550 |
    |   1 |  4093 |   FINAL |   581 |
    |   2 |  2129 |   FINAL |   559 |
    

    编辑

    查询 1

    select * from (
    select 
    @rn:= @rn+1 as rId, 
    admNo,
    examtyp,
    marks
    from table1
    join
    (select @rn:=0) tmp
    where examtyp='CAT1'
    order by examtyp, marks desc
    ) tmp where tmp.admNo=2129
    

    SQL FIDDLE

    | RID | ADMNO | EXAMTYP | MARKS |
    ---------------------------------
    |   2 |  2129 |    CAT1 |   525 |
    

    【讨论】:

    • 谢谢先生,但我需要一个 sql 来对特定考试类型(如 CAT1)中的学生进行排名,而不是所有考试类型。例如,我需要 CAT1 考试中 admNo 4093 的位置,按分数顺序排列
    • 您可以在 where 子句中为您的考试类型添加相应的过滤器...检查编辑
    【解决方案4】:

    试试这个 -

    SELECT q1.rownum
    FROM 
        (
            SELECT *, @rownum:=@rownum + 1 AS rownum
            FROM $table t, (SELECT @rownum:=0) r 
            WHERE examtyp = 'CAT1'
            ORDER BY marks
        ) q1
    WHERE q1.admNo=?
    

    2) 由于您修改了要求以获得相同分数的相同排名,您可能需要做这样的事情 -

    SELECT q1.rownum
    FROM 
        (
            SELECT *, @rownum:=@rownum + 1 AS rownum
            FROM 
                (SELECT DISTINCT marks FROM table1 t WHERE t.examtyp = 'CAT1' ORDER BY t.marks) q2, 
                (SELECT @rownum:=0) r 
        ) q1,
        table1 t2
    WHERE 
        t2.examtyp = 'CAT1'
        AND t2.marks=q1.marks
        AND t2.admNo=?;
    

    以上,你需要在两个地方更改examCategory

    这不是最优化的查询..但它会做你的工作。

    3) 根据您的第三个要求来增加下一个学生的计数,这可能会奏效 -

    SELECT ROWNUM
    FROM
    (
        SELECT q1.marks, min(q1.rownum) AS rownum
        FROM 
        (
            SELECT t1.marks, @rownum:=@rownum + 1 AS rownum
            FROM 
                table1 t1, 
                (SELECT @rownum:=0) r
            WHERE
                t1.examtyp='CAT1'
            ORDER BY t1.marks asc
        ) q1 
        GROUP BY q1.marks
    ) q2,
    table1 t2
    WHERE 
        t2.examtyp = 'CAT1'
        AND t2.marks=q2.marks;
        AND t2.admNo=?;
    

    【讨论】:

    • 谢谢,一切正常。我现在需要一个 sql 来对某个考试类型的学生进行排名,例如。 CAT1 并给出位置,即使在分数有联系的情况下,它也可以给出学生的位置
    • 当学生分数相等时,这个sql不能很好地工作。我需要一个能在学生分数相等时给学生相同药水的sql。谢谢
    • 谢谢,这个查询为分数相同的学生提供了相同的位置,但我希望它计算共享该位置的学生数量,以便考虑到下一个学生在课堂上的正确位置得分高于他/她的学生人数。希望我的语法被理解。再次感谢
    猜你喜欢
    • 1970-01-01
    • 2021-05-21
    • 2016-08-31
    • 2017-11-24
    • 1970-01-01
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多