SQL Server How to get the name of a the student who got max marks in each subject?

c86crjj0  于 9个月前  发布在  Go
关注(0)|答案(9)|浏览(57)

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
wtlkbnrh

wtlkbnrh1#

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 |
uurity8g

uurity8g2#

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

rryofs0p3#

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

dfuffjeb

dfuffjeb4#

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>
thtygnil

thtygnil5#

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

ars1skjm

ars1skjm6#

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

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

tgabmvqs7#

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

qoefvg9y8#

This query will work

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

6tqwzwtp9#

By using GROUP BY and Having clause that give you simple sql query to find maximum marks in each subject

SELECT Name, Subject, Marks from Student GROUP BY (Subject) HAVING Marks=max(Marks);

相关问题