MySQL GROUP BY按category分组无法获取组内最早日期记录问题
问题根因
你原有的SELECT * FROM my_table GROUP BY ifnull(category,id) ORDER BY date DESC写法本身不符合标准SQL规范,仅在MySQL关闭ONLY_FULL_GROUP_BY开关时允许执行。这种写法下非分组列的返回值是不确定的,MySQL不会自动帮你取分组内日期最早的记录,因此会出现结果不符合预期的问题。
解决方案
方案1:MySQL 8.0+ 版本(推荐,简洁高效)
使用窗口函数给每个分组内的记录按日期升序排名,取排名第一的记录即可:
WITH ranked_records AS ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY IFNULL(category, id) ORDER BY `date` ASC ) AS rn FROM my_table ) SELECT name, `date`, category, id FROM ranked_records WHERE rn = 1 ORDER BY `date` DESC;
执行后返回结果完全符合需求:
- category为10的分组返回最早的jean
- category为20的分组返回最早的arnold
- category为NULL的记录按id单独分组全部保留
方案2:MySQL 5.x 低版本兼容写法
通过子查询先拿到每个分组的最小日期,再关联原表匹配对应记录:
SELECT t.* FROM my_table t INNER JOIN ( SELECT IFNULL(category, id) AS group_key, MIN(`date`) AS min_date FROM my_table GROUP BY group_key ) t_group ON IFNULL(t.category, t.id) = t_group.group_key AND t.`date` = t_group.min_date ORDER BY t.`date` DESC;
注意事项
date属于SQL关键字,查询时建议用反引号包裹避免语法报错- 你提供的测试数据插入SQL中表名写为
test,实际执行时请替换为你创建的表名my_table - 如果同一分组内存在多条日期完全相同的最早记录,方案2会返回所有符合条件的记录,如需仅返回一条可额外增加判断规则(比如取最小id)
内容的提问来源于stack exchange,提问作者rudak
相关产品推荐
相关产品推荐

