获取最高分数的Sql查询
表结构如下所示:获取最高分数的Sql查询,sql,sql-server,Sql,Sql Server,表结构如下所示: Student(StudentID int,StudentName varchar(20)) Subject(SubjectID int,SubjectName varchar(20)) Score(ScoreID int、StudentID int、SubjectID int、Score int) 这是数据 Student | StudentID | StudentName | | 1 | John | | 2 | Na
(StudentID int,StudentName varchar(20))Student
(SubjectID int,SubjectName varchar(20))Subject
(ScoreID int、StudentID int、SubjectID int、Score int)Score
Student
| StudentID | StudentName |
| 1 | John |
| 2 | Nash |
| 3 | Albert |
---------------------------
Subject
| SubjectID | SubjectName |
| 1 | Maths |
| 2 | Physics |
| 3 | Chemistry|
| 4 | English |
---------------------------
Score
| ScoreID | StudentID | SubjectID | Score |
| 1 | 1 | 1 | 34 |
| 2 | 1 | 2 | 45 |
| 3 | 1 | 3 | 56 |
| 4 | 2 | 1 | 78 |
| 5 | 2 | 3 | 23 |
| 6 | 2 | 4 | 44 |
| 7 | 3 | 1 | 45 |
| 8 | 3 | 2 | 10 |
| 9 | 3 | 3 | 54 |
| 10 | 3 | 4 | 74 |
-------------------------------------------
Output:
|StudentName | Score | SubjectName |
| John | 45 | Physics |
| John | 56 | Chemistry |
| Nash | 78 | Maths |
| Albert | 74 | English |
------------------------------------
我想写一个查询来获取每个主题的最高分以及他们的分数和主题名称,而不使用Row_Number()、Rank()和densite_Rank()
我已经编写了这个查询,但我认为它可以改进:
select
st.StudentName, Score, B.SubjectID
from
(select
StudentID, Sc.SubjectID, Sc.Score
from
(select
SubjectID, MAX(Score) as 'Score'
from
Score Sc
inner join
subject sb on sc.subjectid = sb.subjectid
group by
SubjectID) A
inner join
score sc on sc.SubjectID = a.SubjectID and sc.Score = A.Score) B
inner join
Student st on st.studentID = B.StudentID
您可以使用ANSI标准的
rank()
或row\u number()
函数。假设您想要所有副本,请使用rank()
:
如果您希望每个科目有一行任意的优等生,请使用row\u number()
在SQL Server中,也可以在不使用子查询的情况下执行此操作:
select top (1) with ties st.StudentName, su.SubjectName, s.Score
from score s join
student st
on s.studentid = st.studentid join
subject su
on s.subjectid = su.subjectid
order by rank() over (partition by su.SubjectName order by s.Score desc)
另一个有趣的选项是apply
——它不使用窗口功能,可以有相当好的性能:
select ss.StudentName, su.SubjectName, ss.Score
from subject su cross apply
(select top (1) with ties s.*
from score s join
student st
on s.studentid = st.studentid join
where s.subjectid = su.subjectid
order by su.score desc
) ss;
您可以使用ANSI标准的
rank()
或row\u number()
函数。假设您想要所有副本,请使用rank()
:
如果您希望每个科目有一行任意的优等生,请使用row\u number()
在SQL Server中,也可以在不使用子查询的情况下执行此操作:
select top (1) with ties st.StudentName, su.SubjectName, s.Score
from score s join
student st
on s.studentid = st.studentid join
subject su
on s.subjectid = su.subjectid
order by rank() over (partition by su.SubjectName order by s.Score desc)
另一个有趣的选项是apply
——它不使用窗口功能,可以有相当好的性能:
select ss.StudentName, su.SubjectName, ss.Score
from subject su cross apply
(select top (1) with ties s.*
from score s join
student st
on s.studentid = st.studentid join
where s.subjectid = su.subjectid
order by su.score desc
) ss;
您可以像下面那样使用
行号
SELECT * FROM
(SELECT st.StudentName, sub.SubjectName, s.Score,
ROW_NUMBER() OVER(partition by sub.SubjectName order by s.Score Desc) as row_no
FROM Score s
LEFT OUTER JOIN Student st on s.StudentID = st.StudentID
LEFT OUTER JOIN Subject sub on s.SubjectID = sub.SubjectID) as tblMain
WHERE row_no = 1
您可以像下面那样使用
行号
SELECT * FROM
(SELECT st.StudentName, sub.SubjectName, s.Score,
ROW_NUMBER() OVER(partition by sub.SubjectName order by s.Score Desc) as row_no
FROM Score s
LEFT OUTER JOIN Student st on s.StudentID = st.StudentID
LEFT OUTER JOIN Subject sub on s.SubjectID = sub.SubjectID) as tblMain
WHERE row_no = 1
这是一种不使用秩或行号的解决方案。此外,为了满足您的输出,这也被大大简化了。希望能有帮助
SELECT st.StudentName ,s.Score ,su.SubjectName FROM (SELECT
SubjectID,MAX(Score) as Max FROM Score GROUP BY SubjectID) a
INNER JOIN Score s on a.SubjectID=s.SubjectID AND a.MAX=s.Score
INNER JOIN Student st on s.StudentID=st.StudentID
INNER JOIN Subject su on s.SubjectID=su.SubjectID
这是一种不使用秩或行号的解决方案。此外,为了满足您的输出,这也被大大简化了。希望能有帮助
SELECT st.StudentName ,s.Score ,su.SubjectName FROM (SELECT
SubjectID,MAX(Score) as Max FROM Score GROUP BY SubjectID) a
INNER JOIN Score s on a.SubjectID=s.SubjectID AND a.MAX=s.Score
INNER JOIN Student st on s.StudentID=st.StudentID
INNER JOIN Subject su on s.SubjectID=su.SubjectID
用您正在使用的数据库标记您的问题。样本数据和期望的结果几乎总是有帮助的。请阅读您希望在出现领带时有什么行为?用您正在使用的数据库标记您的问题。样本数据和期望的结果几乎总是有帮助的。请阅读在发生关系时你想要什么行为?嗨,戈尔丹。谢谢你的帮助。但是您的查询获取的是NULL而不是名称Albert。如果我不能澄清我的问题,请告诉我!另外,在不使用诸如Row_Number()和Rank()之类的函数的情况下,是否仍然可以执行此操作。使用Group By和Max()@Anshul。如果(1)所有
分数。studentid
有效,并且(2)如果没有学生姓名为NULL,我不知道这怎么会返回学生姓名的NULL
。这两种情况似乎都适用于示例数据。您可以设置SQL fiddle、db fiddle或rextester吗?嗨,Gordan。谢谢你的帮助。但是您的查询获取的是NULL而不是名称Albert。如果我不能澄清我的问题,请告诉我!另外,在不使用诸如Row_Number()和Rank()之类的函数的情况下,是否仍然可以执行此操作。使用Group By和Max()@Anshul。如果(1)所有分数。studentid
有效,并且(2)如果没有学生姓名为NULL,我不知道这怎么会返回学生姓名的NULL
。这两种情况似乎都适用于示例数据。您可以设置SQL fiddle、db fiddle或rextester吗?你好,哈桑。谢谢您的帮助,但是您的查询没有得到适当的结果。你能看看上面的预期输出吗?你好,哈桑。谢谢您的帮助,但是您的查询没有得到适当的结果。您可以查看上面的预期输出吗?注意:此查询不会打破平局,并将返回所有最高分!注意:此查询不会打破平局,并将返回所有最高分!