4

I have the following table

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

Here I have a "Student" table I want to get the Name of the student who got
Max marks from each subject from the student table like the following OUTPUT.

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

8 回答 8

9

You can use the ROW_NUMBER function to return only the "best" row per subject:

SQL Fiddle

MS SQL Server 2008 Schema Setup:

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)
;

Query 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 |
于 2013-08-05T12:35:26.353 回答
3

You can use other functions and cte also to get the result..

eg : 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

Eg : 2 : use of cte and dense_rank function

;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;
于 2013-08-25T03:46:16.750 回答
1

This Basic Query should work for your req.

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

Tried in SQLFiddle

Note: Used SQLite for check

于 2017-03-25T08:14:41.863 回答
0
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>
于 2015-09-22T19:24:16.797 回答
0

SELECT Max(Name) as Name, Subject, Max(Marks) as Marks
FROM Student
group by Subject

于 2015-10-03T03:54:39.447 回答
0

A Similar problem :

Write a query to display the name(s) of the students who have secured the maximum marks in each subject, ordered by subject name in ascending order.

If there are multiple toppers, display their names in alphabetical order.

Display it as subject_name and student_name.

O/P:

  • First column - subject_name
  • Second column - student_name

enter image description here

Solution for this problem:

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;
于 2019-07-20T13:50:10.200 回答
0

The below query will work perfectly:

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;
于 2020-03-25T06:48:39.110 回答
0

This query will work

select name,subject,marks from stud where marks in (select max(marks) from stud      group by subject) ;
于 2021-07-02T19:16:48.497 回答