在sql server中,我希望得到类名,学生姓名以及最大分数的最高分。下面给出了

时间:2017-11-24 08:19:04

标签: sql sql-server

我有 StudentDetails 表,如下所示

select * from StudentDetails

enter image description here

我们有 Class 表,如下所示

select * from Class

enter image description here

我知道通过使用分组汇总功能,我们可以通过以下查询轻松显示每个类中获得的最大分数

select C.Name as 'ClassName',
       MAX(SD.Mark) as 'Max Mark' 
from   StudentDetails SD 
       inner join Class C on SD.classid = C.ClassId group by C.Name 

给出以下结果

enter image description here

但现在我需要使用分组汇总功能来显示学生姓名以及每个班级的最大分数。我使用了以下查询,但没有给出预期的结果。

select C.Name as 'ClassName',
       SD.Name as 'Student Name', 
       Max(SD.Mark) as 'Max Mark' 
from   StudentDetails SD 
       inner join Class C on SD.classid = C.ClassId 
group by C.Name,SD.Name

给出以下结果。

enter image description here

此结果与预期不符,我需要一个查询结果

Division A , Mrx , 536
Division B , MrC , 535. 

使用分组汇总功能请有人帮助我..

6 个答案:

答案 0 :(得分:2)

您可以使用派生表。派生表将ClassID与它的MAX(Mark)一起使用。接收查询和联接应用适当的描述。

SELECT C.Name
      ,SD.Name
      ,dT.MaxMark
  FROM ( 
         --Gets the MaxMark per ClassID
         SELECT S.ClassID
               ,MAX(Mark) [MaxMark]
           FROM StudentDetails S
         GROUP BY S.ClassID  
       ) AS dT INNER JOIN StudentDetails SD ON SD.Mark = dT.MaxMark
               INNER JOIN Class C ON C.ClassID = dT.ClassID

提供输出:

Name        Name    MaxMark
Division A  MrX     536
Division B  MrC     535

如果您想检查完整代码:sqlfiddle

答案 1 :(得分:1)

试试这个:

WITH CTE AS(

     select C.Name as 'ClassName',
            MAX(SD.Mark) as 'Max Mark' 
     from   StudentDetails SD 
            inner join Class C on SD.classid = C.ClassId group by C.Name
)
SELECT STudentName,*
FROM CTE
INNER JOIN StudentDetails SD ON Marks = [Max Marks] 

答案 2 :(得分:0)

您想要将学生班级成绩与最高班级成绩进行比较。最简单的方法是使用MAX OVER

select classname, studentname, mark
from
(
  select
    c.name as classname,
    sd.name as studentname,
    sd.mark,
    max(sd.mark) over (partition by sd.class) as class_max_mark
  from studentdetails s
  join class c on c.classid = sd.classid
) analysed
where mark = class_max_mark;

如果您被迫使用GROUP BY,那么您需要:

select
  c.name as classname,
  sd.name as studentname,
  sd.mark
from studentdetails s
join class c on c.classid = sd.classid
where (sd.classid, sd.mark) in
(
  select classid, max(mark)
  from studentdetails
  group by classid
);
但是,

SQL Server不支持具有多个列的IN子句。所以你需要一个稍微混淆查询的连接:

select
  c.name as classname,
  sd.name as studentname,
  sd.mark
from studentdetails s
join class c on c.classid = sd.classid
join
(
  select classid, max(mark) as max_mark
  from studentdetails
  group by classid
) m on m.classid = sd.classid and m.max_mark = sd.mark;

答案 3 :(得分:0)

利用dense_rank

select StudName, ClsName, Mark from 
  (
      select Dense_Rank() over(partition by #Table_studentDetails.classId 
       order by Mark desc) Rank, 
      #Table_studentDetails.Name StudName, #Table_Class.Name ClsName,Mark
      from #Table_studentDetails inner join #Table_Class on 
      #Table_studentDetails.classid = #Table_Class.classid

    )T
 where Rank = 1

答案 4 :(得分:0)

您可以在WHERE

中使用相关子查询
select C.Name as 'ClassName',
       SD.name,
       SD.Mark as 'Max Mark' 
from   StudentDetails SD 
inner join Class C on SD.classid = C.ClassId
where sd.mark = (select max(mark) from StudentDetails s where sd.classid = s.classid)

答案 5 :(得分:0)

试试这个:

select B.Name, A.Name, A.Mark from (
    select Name, Mark, ClassId, MAX() over (partition by ClassId) as MaxMark from StudentDetails
) as A join Class as C on A.ClassId = C.ClassId
where A.Mark = A.MaxMark