SQL报错 column t1.col_1 must appear in the GROUP BY clause or be used in an aggregate function

在pg数据库写sql 的时候报错.因为mysql可以执行的语句到pg数据库不行了,看这篇文章就能理解了.

column "t1.col_1" must appear in the GROUP BY clause or be used in an aggregate function

什么意思?列t1.col_1必须出现在GROUP BY子句中或在聚合函数中使用。其实,这个错误遇到得多了,都能够避免,按照错误提示修改即可获得我们想要的结果。

但,现在想聊两个问题:

1、聚合查询时,SELECT子句中能有什么内容?
2、为什么聚合后不能再使用原表的列了?


解答问题1

聚合查询时,SELECT子句中可以有3种内容:

  • GROUP BY子句中出现的列名
  • 使用聚合函数(SUM、MAX、AVG等)
  • 常量

MySQL数据库是支持聚合后在SELECT使用原表的列,但最好养成习惯,不要去用。


解答问题2

第2个问题可以从两个角度去解答:业务逻辑和执行逻辑

业务逻辑,也就是用实例去理解,比如有下面这张表ClassScore

image-20220908164113166

运行下面这段代码,肯定报错

SELECT class, score
FROM ClassScore 
GROUP BY class;

这段代码想表达什么含义呢?班级每个人的成绩?班级分数?什么分数呢?表达含义不清。

GROUP BY聚合后,表达的结果是整个班级的,而分数是个人的,个人分数用于表达整个班级的分数,所以报错。但只要求最高分,平均分等就可以了,这才是班级的属性,班级的属性只能是统计性质的属性

比如改成这样可以求班级平均分:

SELECT class, AVG(score)
FROM ClassScore 
GROUP BY class;

执行逻辑,在不使用GROUP BY聚合时,SQL的操作对象是单行的数据(也即元素),0阶对象,但在聚合之后呢,操作对象变为多行聚集在一起的整体,是“行的集合”,1阶对象,比如上面的两行A班和3行B班的数据。而原表的列名(其实叫做属性更加合适)是单行数据的属性,如果在聚合之后再用单行属性表示整体属性恐怕就不合适了吧。

比如,这个班80分,我们很难理解这句话,如果改成:

这个班的平均分80分。

或者

这个班的小王80分。

两者都可以,前者是班级属性,是集合的属性,后者是个人属性,元素的属性,要一一对应,不能混用。

posted @ 2022-09-11 19:02  哩个啷个波  阅读(774)  评论(0编辑  收藏  举报