基于MySQL变更记录查询指定月份学生所在教室的技术问询
解决指定月份学生所在教室的查询问题
首先,咱们得先理清你的需求核心:找到每个学生在指定月份(比如2018年10月)截止时,最后一次变更后的教室——因为规则是变更前一直用原教室,所以截止到当月最后一天,最新的一次教室分配就是他们当前的教室。
你现有的查询存在两个关键问题:
GROUP BY student后直接SELECT x.*在MySQL严格模式下会报错,即使关闭严格模式,也无法保证取到的是该学生最后一次变更的记录(MySQL会随机选取分组内的某条记录);- LEFT JOIN的逻辑没有聚焦到“最后一次有效变更”这个核心需求点上。
推荐的两种实现方式
方法1:子查询+关联(兼容所有MySQL版本)
先给每个学生找出截止到指定月份最后一天的最新记录日期,再关联原表拿到对应的教室:
SELECT t.student, t.classroom FROM my_table t INNER JOIN ( -- 子查询:获取每个学生在指定日期前的最后一次变更日期 SELECT student, MAX(date) AS latest_date FROM my_table WHERE date <= LAST_DAY('2018-10-01') GROUP BY student ) AS latest_records ON t.student = latest_records.student AND t.date = latest_records.latest_date;
方法2:窗口函数(MySQL 8.0及以上版本推荐)
用ROW_NUMBER()窗口函数给每个学生的记录按日期降序排序,取排序第一的那条(也就是最新的记录):
SELECT student, classroom FROM ( SELECT student, classroom, -- 按学生分组,日期倒序排,最新的记录标记为1 ROW_NUMBER() OVER (PARTITION BY student ORDER BY date DESC) AS record_rank FROM my_table WHERE date <= LAST_DAY('2018-10-01') ) AS ranked_records WHERE record_rank = 1;
验证结果
针对你提供的表数据,查询2018年10月的结果应该是:
| Student | Classroom |
|---|---|
| 1 | 104 |
| 2 | 103 |
| 3 | 104 |
这个结果完全符合规则:学生1最后一次变更是2018-03-01的104(11月才换106,10月仍在104);学生2最后一次变更是2018-06-01的103;学生3是2018-09-01的104。
内容的提问来源于stack exchange,提问作者Marcox105
相关产品推荐
相关产品推荐

