【问题标题】:Class wise, student name who has max aggregate of marks班级明智,具有最大总分的学生姓名
【发布时间】:2023-03-26 01:31:01
【问题描述】:

假设我有一个如下表:

Class   |   Subject | Student   | Marks
----------------------------------------
1       |   Maths   |   A       |   70   
1       |   Eng     |   B       |   80
1       |   IT      |   A       |   90 
1       |   IT      |   C       |   80 
2       |   Maths   |   D       |   60   
2       |   Eng     |   E       |   75
2       |   Maths   |   E       |   90 
2       |   IT      |   F       |   80 
3       |   Maths   |   A       |   160   
3       |   Eng     |   B       |   165
3       |   IT      |   G       |   90 

我希望输出为

Class   |   Student     | Marks
----------------------------------------
1       |       A       |   160   
2       |       E       |   165
3       |       B       |   165 

即结果包含班级明智的学生姓名,其总分最高。 如何为此编写 SQL 查询? 例如对于第 1 课,学生 A 有 70+90 = 160,超过 B 和 C 都为 80。

【问题讨论】:

    标签: mysql sql database


    【解决方案1】:

    一种解决方案是计算学生每堂课的最高分,并将其用作过滤连接:

    select  ClassStudentSum.*
    from    (
            select  class
            ,       student
            ,       sum(Marks) as SumMarks
            from    YourTable
            group by
                    class
            ,       student
            ) as ClassStudentSum
    join    (
            select  class
            ,       max(SumMarks) as MaxSumMarks
            from    (
                    select  class
                    ,       student
                    ,       sum(Marks) as SumMarks
                    from    YourTable
                    group by
                            class
                    ,       student
                    ) ClassStudentSum2
            group by
                    class
            ) MaxPerClass
    on      MaxPerClass.class = ClassStudentSum.class
            and MaxPerClass.MaxSumMarks = ClassStudentSum.SumMarks
    

    Live example at SQL Fiddle.

    【讨论】:

    • 该问题被否决,因为否决按钮的工具提示以“此问题未显示任何研究工作”开头。
    • @Andomar:“这有多难” --- 老实说,这个查询并不难。它臃肿 - 是的,但它很简单。在其他一些 DBMS 中,可以使用 WITH 和分析函数对其进行简化,并且看起来更友好
    【解决方案2】:

    一种更传统(也更慢)的方法...

    SELECT x.*
      FROM
         ( SELECT class
                , student
                , SUM(marks) ttl_marks
             FROM yourtable 
            GROUP
               BY class
                , student
         ) x
      LEFT 
      JOIN
         ( SELECT class
                , student
                , SUM(marks) ttl_marks
             FROM yourtable 
            GROUP
               BY class
                , student
         ) y
        ON y.class = x.class
       AND y.ttl_marks > x.ttl_marks
     WHERE y.class IS NULL;
    

    【讨论】:

      【解决方案3】:

      试试这个查询

      查询 1

      select a.*, if(@prv=class, 1, 0) as flag, @prv:=class from 
      (select class,student, sum(marks) as total from table1 
      group by class, student
      order by class, total desc)a join (select @prv:=0)tmp
      where if(@prv=class, 1, 0) = 0
      

      SQL FIDDLE

      | CLASS | STUDENT | TOTAL | FLAG | @PRV:=CLASS |
      ------------------------------------------------
      |     1 |       A |   160 |    0 |           1 |
      |     2 |       E |   165 |    0 |           2 |
      |     3 |       B |   165 |    0 |           3 |
      

      希望对你有帮助

      【讨论】:

      • +1 这会奏效,而且速度也很快。虽然是非标准 SQL。
      • 假设没有关系
      • 是的..它只显示前一个,所以如果有平局就只有1个学生。
      【解决方案4】:

      正确的查询是:

      select class, student, sums.mark
      from (select class, student, sum(marks) as mark
            from student
            group by class, student
            order by mark desc) sums
      group by class
      

      【讨论】:

        【解决方案5】:

        使用此语句。它是有效的

           select Class,Student,Marks 
        from(
            select Class,Student,Marks,Dense_rank() over( partition by class order by marks desc) Rank
              from(Select Class, Student,Max(Marks) Marks 
                from(select Class, Student,Sum(Marks) Marks from Temp14
                  group by Class,Student
                  order by 1)
                group by Class, Student
                order by 1)
            )
        where Rank=1
        

        试试这个。

        【讨论】:

        • 仅供参考:这个问题被标记为MySQL :)
        • 哦,我没有看到标签,但它在Oracle and Sql 中工作。我对Mysql 了解不多。
        【解决方案6】:

        我猜这是一个更简单的查询。它工作正常。无需连接。

        SELECT class,
        (
        SELECT student FROM yourtable
        WHERE class = YT.class GROUP BY student
        ORDER BY SUM(marks) DESC
        LIMIT 1
        ) AS student,
        (
        SELECT SUM(marks) FROM yourtable
        WHERE class = YT.class GROUP BY student
        ORDER BY SUM(marks) DESC
        LIMIT 1
        ) AS marks
        FROM yourtable AS YT
        GROUP BY class

        【讨论】:

        • 假设没有关系。
        【解决方案7】:
            SQL> with cte as
              2  (select class, student, sum(marks) marks
              3  from engineer
              4  group by class, student
              5  order by class)
              6  select class, student, marks
              7  from (select class, student, marks, dense_rank() over(partition by class order by marks desc) rank
              8  from cte)
              9  where rank=1;
        
                 CLASS S      MARKS
            ---------- - ----------
                     1 A        160
                     2 E        165
                     3 B        165
        
            SQL>
        
        Here the most important inner query is for cte table. Resulr set created for this one will be as below.
        
        SQL> select class, student, sum(marks)
          2  from engineer
          3  group by class, student
          4  order by class;
        
             CLASS S SUM(MARKS)
        ---------- - ----------
                 1 A        160
                 1 B         80
                 1 C         80
                 2 D         60
                 2 E        165
                 2 F         80
                 3 A        160
                 3 B        165
                 3 G         90
        
        9 rows selected.
        

        【讨论】:

          猜你喜欢
          • 2021-10-18
          • 1970-01-01
          • 1970-01-01
          • 2013-06-05
          • 2023-03-25
          • 2016-07-13
          • 2012-02-06
          • 1970-01-01
          • 2021-07-11
          相关资源
          最近更新 更多