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
:
运行下面这段代码,肯定报错
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分。
两者都可以,前者是班级属性,是集合的属性,后者是个人属性,元素的属性,要一一对应,不能混用。