MySQL查询为每条返回记录添加总记录数字段遇#42000报错,求解决方案
解决MySQL聚合查询与ONLY_FULL_GROUP_BY模式的冲突问题
报错原因分析
你遇到的这个错误是MySQL的only_full_group_by SQL模式导致的,说白了就是:
- 你的查询里用了聚合函数
count(*),但没加GROUP BY子句。 - 当
only_full_group_by模式开启时,MySQL有个硬性要求:所有出现在SELECT列表里的非聚合字段(比如LS.id、LS.parent_livestock_species_id这些没被聚合函数包裹的列),必须同时出现在GROUP BY子句中。 - 这是因为MySQL没法确定这些非聚合列该和聚合结果怎么对应匹配,所以直接抛出了语法错误。
解决方案:让每行都带上总记录数
你的需求是查询返回的每一行都显示整个结果集的总记录数,直接用GROUP BY不行(分组会合并行,达不到每行都显示总条数的效果),这里有两种可行的方法:
方法1:使用窗口函数(MySQL 8.0+ 推荐)
窗口函数COUNT(*) OVER()可以直接计算整个结果集的总记录数,不需要GROUP BY,完美匹配你的需求:
SELECT LS.id AS livestock_id, LS.parent_livestock_species_id AS parent_livestock_species_id, LS.livestock_species_name_en AS livestock_species_name_en, IFNULL(LSN.livestock_species_name, LS.livestock_species_name_en) AS livestock_species_name, LSN.description AS description, LS.image_link AS image_link, COUNT(*) OVER() AS record_number -- 窗口函数计算总记录数 FROM LivestockSpecies AS LS LEFT JOIN LivestockSpeciesName AS LSN ON LSN.livestock_species_id = LS.id AND LSN.language_id = 1 WHERE LS.id = 1 OR LS.parent_livestock_species_id = 1
方法2:子查询获取总记录数(兼容MySQL 5.7及以下)
如果你的MySQL版本不支持窗口函数,可以先通过子查询算出总记录数,再用笛卡尔积关联到原查询结果:
SELECT LS.id AS livestock_id, LS.parent_livestock_species_id AS parent_livestock_species_id, LS.livestock_species_name_en AS livestock_species_name_en, IFNULL(LSN.livestock_species_name, LS.livestock_species_name_en) AS livestock_species_name, LSN.description AS description, LS.image_link AS image_link, total.record_number FROM LivestockSpecies AS LS LEFT JOIN LivestockSpeciesName AS LSN ON LSN.livestock_species_id = LS.id AND LSN.language_id = 1 -- 关联总记录数的子查询 CROSS JOIN ( SELECT COUNT(*) AS record_number FROM LivestockSpecies AS LS_sub LEFT JOIN LivestockSpeciesName AS LSN_sub ON LSN_sub.livestock_species_id = LS_sub.id AND LSN_sub.language_id = 1 WHERE LS_sub.id = 1 OR LS_sub.parent_livestock_species_id = 1 ) AS total WHERE LS.id = 1 OR LS.parent_livestock_species_id = 1
补充说明
你最初的写法里用count(*)试图获取总条数,但这种方式在无GROUP BY的情况下,要么触发only_full_group_by报错,要么(关闭该模式后)会把所有查询结果合并成一行,得到的count是1,完全不符合你想要每行都显示总记录数的需求,所以必须用上面两种方法来实现。
内容的提问来源于stack exchange,提问作者AndreaNobili
相关产品推荐
相关产品推荐

