You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL分组查询报错:如何获取各课程中学生首次出现的记录?

解决每个课程中学生首次出现记录的查询问题

首先,你原来的查询报错是因为GROUP BY Course时,SELECT子句里的StudentName、Studentmailid、Score既没有包含在GROUP BY分组字段中,也没有使用聚合函数(比如MAX()、MIN()),这不符合SQL的标准规范,数据库无法确定要返回这些字段的哪一个值,所以会抛出错误。

你的需求是获取每个课程+学生组合的首次出现记录(比如Student1在Course A的第一条记录,Student2在Course A的第一条,Student1在Course B的第一条),下面提供几种通用的解决方案,适用于不同的数据库环境:

方法一:使用窗口函数(推荐,适用于MySQL 8+、PostgreSQL、SQL Server等)

窗口函数ROW_NUMBER()可以轻松实现分组取第一条记录的需求。我们先按Course和StudentName分组,给每个组内的记录按插入顺序(假设你有一个自增主键id,用来判断记录的先后顺序)编号,然后筛选出编号为1的记录:

SELECT StudentName, Course, Studentmailid, Score
FROM (
    SELECT 
        *,
        ROW_NUMBER() OVER (
            PARTITION BY Course, StudentName 
            ORDER BY id  -- 这里的id是表中自增主键,用来确定记录的先后顺序
        ) AS row_num
    FROM StudentTable
) AS temp_table
WHERE row_num = 1;

如果你的表没有自增主键,也可以用其他能确定记录顺序的字段(比如创建时间create_time)替换id。如果实在没有这类字段,虽然不推荐,但可以尝试用Score或其他字段排序,但结果可能和预期有偏差。

方法二:使用关联子查询(适用于MySQL 5.x等不支持窗口函数的版本)

如果你的数据库不支持窗口函数,可以通过子查询先找出每个Course+StudentName组合的最早记录的标识(比如最小的id),再关联原表获取完整数据:

SELECT s.StudentName, s.Course, s.Studentmailid, s.Score
FROM StudentTable s
INNER JOIN (
    SELECT Course, StudentName, MIN(id) AS earliest_id
    FROM StudentTable
    GROUP BY Course, StudentName
) AS grouped_s ON s.id = grouped_s.earliest_id;

验证结果

针对你的测试数据,执行以上任意一种查询,都会返回你想要的记录:

  • Student1 | A | student1@gmail.com | 80
  • Student2 | A | student2@gmail.com | 70
  • Student1 | B | student2@gmail.com | 70

完全符合你预期的记录1、3、4。

内容的提问来源于stack exchange,提问作者user13597631

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 08:32:48