zoukankan      html  css  js  c++  java
  • mysql学生成绩排名,分组取前 N 条记录

    转载  https://blog.csdn.net/jslcylcy/article/details/72627762

    score表:

    CREATE TABLE `score` (
      `student_id` int(10) DEFAULT NULL,
      `class_id` int(10) DEFAULT NULL,
      `score` int(5) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
    • 1
    • 2
    • 3
    • 4
    • 5

    字段 student_id 学生 id ,class_id:班级 id ,score:分数 
    数据准备:

    insert into score values(1,1,100),(2,1,93),(3,1,89),(4,1,96),(5,2,98),(6,2,97),(7,2,90),(8,2,88),(9,1,96);

    表结构如下:

    mysql> select * from score;
    +------------+----------+-------+
    | student_id | class_id | score |
    +------------+----------+-------+
    |          1 |        1 |   100 |
    |          2 |        1 |    93 |
    |          3 |        1 |    89 |
    |          4 |        1 |    96 |
    |          5 |        2 |    98 |
    |          6 |        2 |    97 |
    |          7 |        2 |    90 |
    |          8 |        2 |    88 |
    |          9 |        1 |    96 |
    +------------+----------+-------+
    9 rows in set (0.00 sec)

    1.取每个班级前两名的学生(包含并列第二名)

    mysql> select * from score s1 where (select count(0) from score s2 where s1.class_id = s2.class_id and s1.score < s2.score) < 2;
    +------------+----------+-------+
    | student_id | class_id | score |
    +------------+----------+-------+
    |          1 |        1 |   100 |
    |          4 |        1 |    96 |
    |          5 |        2 |    98 |
    |          6 |        2 |    97 |
    |          9 |        1 |    96 |
    +------------+----------+-------+
    5 rows in set (0.00 sec)

    sql 解释:取表 s1的数据,这些数据中 class_id 和 s2 class_id相同的数据下,比 s1的 score 分数大的 s2的数据条目必须小于2

    或者使用 left join 的方式:

    mysql> select s1.* from score s1 left join score s2 on s1.class_id = s2.class_id and s1.score<s2.score group by s1.class_id,s1.student_id,s1.score having count(s2.student_id)<2;
    +------------+----------+-------+
    | student_id | class_id | score |
    +------------+----------+-------+
    |          1 |        1 |   100 |
    |          4 |        1 |    96 |
    |          9 |        1 |    96 |
    |          5 |        2 |    98 |
    |          6 |        2 |    97 |
    +------------+----------+-------+
    5 rows in set (0.00 sec)

    2.取学生分数数据且表示排名

    mysql> select s1.*,(select count(0) + 1 from score s2 where s2.score > s1.score)rank from score s1;
    +------------+----------+-------+------+
    | student_id | class_id | score | rank |
    +------------+----------+-------+------+
    |          1 |        1 |   100 |    1 |
    |          2 |        1 |    93 |    6 |
    |          3 |        1 |    89 |    8 |
    |          4 |        1 |    96 |    4 |
    |          5 |        2 |    98 |    2 |
    |          6 |        2 |    97 |    3 |
    |          7 |        2 |    90 |    7 |
    |          8 |        2 |    88 |    9 |
    |          9 |        1 |    96 |    4 |
    +------------+----------+-------+------+
    9 rows in set (0.00 sec)

    sql解释:将 s2中比s1中分数大的条目显示出来就行了(count 时需要加1)

    3.取学生成绩数据,表示班级排名

    mysql> select s1.*,(select count(0) + 1 from score s2 where s1.class_id = s2.class_id and s2.score > s1.score)rank from score s1 order by class_id,rank;
    +------------+----------+-------+------+
    | student_id | class_id | score | rank |
    +------------+----------+-------+------+
    |          1 |        1 |   100 |    1 |
    |          4 |        1 |    96 |    2 |
    |          9 |        1 |    96 |    2 |
    |          2 |        1 |    93 |    4 |
    |          3 |        1 |    89 |    5 |
    |          5 |        2 |    98 |    1 |
    |          6 |        2 |    97 |    2 |
    |          7 |        2 |    90 |    3 |
    |          8 |        2 |    88 |    4 |
    +------------+----------+-------+------+
    9 rows in set (0.00 sec)

    与之前一样,但过滤条件中只需要计算班级相同的数据条目

    4.取每个班级前两名(并列的只取前面的数据)

  • 相关阅读:
    剑指Offer-30.连续子数组的最大和(C++/Java)
    剑指Offer-29.最小的K个数(C++/Java)
    UVA 1616 Caravan Robbers 商队抢劫者(二分)
    UVA 10570 Meeting with Aliens 外星人聚会
    UVA 11093 Just Finish it up 环形跑道 (贪心)
    UVA 12673 Erratic Expansion 奇怪的气球膨胀 (递推)
    UVA 10954 Add All 全部相加 (Huffman编码)
    UVA 714 Copying Books 抄书 (二分)
    UVALive 3523 Knights of the Round Table 圆桌骑士 (无向图点双连通分量)
    codeforecs Gym 100286B Blind Walk
  • 原文地址:https://www.cnblogs.com/wen-zi/p/9078046.html
Copyright © 2011-2022 走看看