Sql server 2008 按表达式分组

Sql server 2008 按表达式分组,sql-server-2008,Sql Server 2008,这是我的小提琴手贝奇; 我们有分数表, SID=学生ID CID=课程ID 我们想得到一个学生的SID,他在“C1”课程中获得了最高的分数 这是我的解决方案 SELECT DISTINCT SID FROM GRADES WHERE GRADE = (SELECT max(GRADE) FROM GRADES GROUP BY CID HAVING CID = 'C1') 在我看来,它是错误的,我该如何修复它呢?您必须筛选适当的课程日期,按成绩描述排序,并获得第一

这是我的小提琴手贝奇;

我们有分数表, SID=学生ID CID=课程ID

我们想得到一个学生的SID,他在“C1”课程中获得了最高的分数

这是我的解决方案

SELECT DISTINCT SID
FROM GRADES
WHERE GRADE =
    (SELECT max(GRADE)
     FROM GRADES
     GROUP BY CID HAVING CID = 'C1')

在我看来,它是错误的,我该如何修复它呢?

您必须筛选适当的课程日期,按成绩描述排序,并获得第一行

SELECT
  SID
FROM grades
WHERE CID = 'C1'
ORDER BY GRADE DESC
LIMIT 1;
或者使用以下命令:

SELECT
  SID
FROM grades G1
WHERE CID = 'C1'
 AND GRADE = (SELECT MAX(GRADE) FROM grades G2 WHERE G2.CID = G1.CID)
SELECT TOP 1 WITH TIES
  SID
FROM grades
WHERE CID = 'C1'
ORDER BY GRADE DESC
更新

上述查询也适用于SQL Server

但你也可以用这个:

SELECT TOP 1
  SID
FROM grades
WHERE CID = 'C1'
ORDER BY GRADE DESC
如果课程中有多个学生成绩最高,而您想要所有学生,您可以使用以下方法:

SELECT
  SID
FROM grades G1
WHERE CID = 'C1'
 AND GRADE = (SELECT MAX(GRADE) FROM grades G2 WHERE G2.CID = G1.CID)
SELECT TOP 1 WITH TIES
  SID
FROM grades
WHERE CID = 'C1'
ORDER BY GRADE DESC
给马库斯·亚当斯

测试日期:


这是错误的,因为您选择了与所选课程中最高分数相同的所有学生。 你只需要那些真正上过这门课的学生。为此,您还需要将课程的选择添加到主查询,而不仅仅是子查询

你可以这样写:

SELECT DISTINCT
  g.SID
FROM
  GRADES g
WHERE
  g.CID = 'C5' AND
  g.GRADE = (SELECT max(g1.GRADE)
     FROM GRADES g1
     WHERE g1.CID = g.CID)
这将返回所有成绩最高的学生。如果他们得到相同的分数,这可能是多个学生,但如果你有这样的疑问,这似乎是合乎逻辑的。如果你不想这样,你可以用哈姆雷特·哈科比安的答案,这将给你一个成绩最高的学生

注意,我之所以添加DISTINCT,是因为您的示例中有两个数据。目前,学生S1的最高成绩是同一成绩的两倍,这就是为什么如果你不加区分,它会出现两次


我认为这是错误的。但是它有效吗?你需要最高年级的学生还是像前10名那样的一些成绩最好的学生?您希望它如何工作?什么是正确的输出?只需要C1课程的高分学生。它是有效的:除了例外,它是错误的,因为你得到的学生从来没有参加过这门课程。再试一次。如果有多个学生的成绩与C1中的最高成绩相同,该怎么办course@DjMix因为您的工作台是在MS SQL SERVER中创建的。您是否使用MSSQL Server?考虑在子查询中替换G2CID= G1.CID中的哪一个字值,如G2.CID=“C1”。至少在MySQL上,它会提高性能,因为它会将子查询从相关依赖变为非相关。它将只运行一次子查询,而不是针对reach行。@MarcusAdams,我认为优化器将为这两个行生成等效的计划。@HamletHakobyan,我在发表评论之前对此进行了测试。它在v5.1.65上没有,尽管它可能与版本有关。这比原始版本更好吗?您的答案与我的类似,此查询将C1分组并获得最高分数,并使用此分数调用SID,如果有类似的分数,此查询将失败,我错了吗?这与我的问题类似:请尝试使用“C5”进行查询,您将理解这一点。如果有两名学生成绩相同,C1课程的信息最高成绩是goneOops。我懂了。在答案中添加了改进的查询。 (1 row(s) affected) StmtText ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |--Nested Loops(Inner Join, WHERE:([Expr1002]=[Test].[dbo].[GRADES].[GRADE] as [G1].[GRADE])) |--Stream Aggregate(DEFINE:([Expr1002]=MAX([Test].[dbo].[GRADES].[GRADE] as [G2].[GRADE]))) | |--Clustered Index Scan(OBJECT:([Test].[dbo].[GRADES].[PK__GRADES__4606D4B55925FD88] AS [G2]), WHERE:([Test].[dbo].[GRADES].[CID] as [G2].[CID]='C1')) |--Clustered Index Scan(OBJECT:([Test].[dbo].[GRADES].[PK__GRADES__4606D4B55925FD88] AS [G1]), WHERE:([Test].[dbo].[GRADES].[CID] as [G1].[CID]='C1')) (4 row(s) affected)
--SET SHOWPLAN_TEXT ON
SELECT
  SID
FROM grades G1
WHERE CID = 'C1'
 AND GRADE = (SELECT MAX(GRADE) FROM grades G2 WHERE G2.CID = 'C1')
(1 row(s) affected) StmtText ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |--Nested Loops(Inner Join, WHERE:([Expr1002]=[Test].[dbo].[GRADES].[GRADE] as [G1].[GRADE])) |--Stream Aggregate(DEFINE:([Expr1002]=MAX([Test].[dbo].[GRADES].[GRADE] as [G2].[GRADE]))) | |--Clustered Index Scan(OBJECT:([Test].[dbo].[GRADES].[PK__GRADES__4606D4B55925FD88] AS [G2]), WHERE:([Test].[dbo].[GRADES].[CID] as [G2].[CID]='C1')) |--Clustered Index Scan(OBJECT:([Test].[dbo].[GRADES].[PK__GRADES__4606D4B55925FD88] AS [G1]), WHERE:([Test].[dbo].[GRADES].[CID] as [G1].[CID]='C1')) (4 row(s) affected)
SELECT DISTINCT
  g.SID
FROM
  GRADES g
WHERE
  g.CID = 'C5' AND
  g.GRADE = (SELECT max(g1.GRADE)
     FROM GRADES g1
     WHERE g1.CID = g.CID)