SQL聚合查询中SELECT表名.*与*的差异及GROUP BY报错原因问询
SQL中SELECT
reviews.* 和 * 在GROUP BY场景下的执行差异说明 第一个SQL执行成功的原因
当你使用 GROUP BY reviews.review_id 时,只要 reviews.review_id 是reviews表的主键/唯一非空键,数据库就可以确认**reviews表的所有列和review_id存在功能依赖关系**:同一个review_id对应的reviews表其他字段值都是唯一确定的。
此时SELECT reviews.*中的所有列都满足「依赖GROUP BY键」的要求,符合ONLY_FULL_GROUP_BY(现代数据库默认开启的SQL标准校验模式)的规则,因此可以正常执行。
替换为*后报错的原因
SELECT *等价于查询JOIN关联后两张表的所有列,也就是会包含comments表的所有字段。
此时你的GROUP BY子句只有reviews.review_id,comments表的所有字段既没有出现在GROUP BY列表中,也没有被COUNT/MAX/MIN这类聚合函数包裹。而一个review_id通常会对应多条comments记录,同一个分组内comments表的字段存在多个不同的值,数据库无法确定要返回哪一个值,因此会抛出column must appear in GROUP BY clause or be used in an aggregate function的校验错误。
补充说明
如果确实需要查询comments表的字段,有两种合法写法:
- 将需要返回的
comments表字段添加到GROUP BY子句中(注意会改变分组粒度,最终统计的comment_count也会对应变化) - 对需要返回的
comments表字段使用聚合函数处理,比如用GROUP_CONCAT(comments.content)合并同一个分组下的所有评论内容 - 部分低版本MySQL默认关闭
ONLY_FULL_GROUP_BY校验,此时写SELECT *可能不会报错,但返回的comments表字段值是随机选取的,结果不可控,不建议使用。
内容的提问来源于stack exchange,提问作者Parzival_89
相关产品推荐
相关产品推荐

