【问题标题】:How to get the name of a the student who got max marks in each subject?如何获得在每个科目中获得最高分的学生的姓名?
【发布时间】:2013-08-05 12:28:56
【问题描述】:

我有下表

 Name  |  Subject  | Marks
 --------------------------
 a        M          20
 b        M          25  
 c        M          30
 d        C          44 
 e        C          45
 f        C          46 
 g        H          20

这里我有一个“学生”表,我想获取获得的学生的姓名
学生表中每个科目的最高分数,如下面的输出。

 Name | Subject | Marks  
 c        M        30
 f        c        46
 g        h        20

【问题讨论】:

  • 我觉得 SO 也有一些 Homework 标签!
  • 将你的练习委托给互联网社区不会让你得到这个结果。

标签: sql sql-server sql-server-2008 sql-server-2005 sql-server-2008-r2


【解决方案1】:

您可以使用 ROW_NUMBER 函数仅返回每个主题的“最佳”行:

SQL Fiddle

MS SQL Server 2008 架构设置

CREATE TABLE Student
    ([Name] varchar(1), [Subject] varchar(1), [Marks] int)
;

INSERT INTO Student
    ([Name], [Subject], [Marks])
VALUES
    ('a', 'M', 20),
    ('b', 'M', 25),
    ('c', 'M', 30),
    ('d', 'C', 44),
    ('e', 'C', 45),
    ('f', 'C', 46),
    ('g', 'H', 20)
;

查询 1

SELECT Name, Subject, Marks
FROM(
  SELECT *, ROW_NUMBER()OVER(PARTITION BY Subject ORDER BY Marks DESC) rn
    FROM dbo.Student
)X
WHERE rn = 1

Results

| NAME | SUBJECT | MARKS |
--------------------------
|    f |       C |    46 |
|    g |       H |    20 |
|    c |       M |    30 |

【讨论】:

  • 其实在我心里。但是为查询 +1。我推荐这个查询。
【解决方案2】:

您也可以使用其他函数和 cte 来获得结果..

例如:1

select B.Name,
       A.Subject,
       B.Marks
from ( select Subject,
              max(Marks) as High_Marks
         from Student
       group by Subject
     ) a
  join Student b
    on a.subject = b.subject
   and a.high_Marks = b.Marks

例如 : 2 : cte 和dense_rank 函数的使用

;WITH cte

AS

(

SELECT

   [Name],

   [Subject],

   [Marks],

   dense_rank() over(partition BY [Subject] order by [Marks] DESC) AS Rank

FROM Student

)

SELECT * FROM cte WHERE Rank = 1;

【讨论】:

    【解决方案3】:

    此基本查询应该适用于您的请求。

    SELECT Name, Subject, Max(Marks)
    FROM Student
    GROUP by Subject;
    

    SQLFiddle试过

    注意:使用 SQLite 进行检查

    【讨论】:

    • 一般来说,这是行不通的。您尚未指定名称应来自具有最大标记的同一行。尽管这在 SQLite 中有效,但 MySQL 给出了错误的名称。 PosgreSQL 和 MS SQL Server 都正确报告错误“列 'Student.Name' 在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中。”
    【解决方案4】:
    SQL> with cte as
      2  (
      3  select name, subject, marks, dense_rank() over (partition by subject order
    by marks desc) rnk
      4  from student)
      5  select name, subject, marks
      6  from cte
      7  where rnk=1;
    
    N S      MARKS
    - - ----------
    f c         46
    c m         30
    
    SQL>
    

    【讨论】:

      【解决方案5】:

      SELECT Max(名称)作为名称、主题,Max(标记)作为标记
      FROM 学生
      group by 主题

      【讨论】:

      • 此解决方案不会返回正确的名称
      【解决方案6】:

      类似的问题

      编写查询以显示在每个科目中获得最高分的学生的姓名,按科目名称升序排列。

      如果有多个排行榜,请按字母顺序显示他们的名字。

      显示为 subject_name 和 student_name。

      O/P:

      • 第一列 - subject_name
      • 第二列 - 学生姓名

      这个问题的解决方案:

      SELECT subject_name,student_name 
          from Student s 
              inner join Mark m on s.student_id=m.student_id
              inner join Subject su on m.subject_id=su.subject_id
              inner join (select subject_id
                                ,max(value) as maximum 
                                    from Mark ma group by subject_id
                          ) highmarks 
                              ON highmarks.subject_id=m.subject_id 
                                  AND highmarks.maximum=m.value
                  order by subject_name,student_name;
      

      【讨论】:

        【解决方案7】:

        以下查询将完美运行:

        select subject_name,student_name from student
        inner join mark m using(student_id)
        inner join subject su using(subject_id)
        inner join (select subject_id,max(value) as maximum from mark m group by subject_id)
        highestmark using(subject_id) where highestmark.maximum = m.value
        order by subject_name,student_name;
        

        【讨论】:

          【解决方案8】:

          这个查询会起作用

          select name,subject,marks from stud where marks in (select max(marks) from stud      group by subject) ;
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-12-09
            • 2021-11-04
            • 1970-01-01
            • 2022-01-20
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多