MySQL GROUP BY和聚合函数

聚合函数

使用sql的过程中有可能用到统计汇总的情况下就要使用聚合函数,常用的有5种。

  • count():计算表中的记录数(行数)
  • sum() : 计算表中数值列中数据的合计值
  • avg() : 计算表中数值列中数据的平均值
  • max() : 求出表中任意列中数据的最大值
  • min() : 求出表中任意列中数据的最小值

示例数据库

数据库

1.count 计算行数

计算全部行数:
计算全部行数直接使用count(*)函数就可以

SELECT
    COUNT(*) 
FROM
    product;

执行结果:

COUNT(*) 
--------
8

1.1 不计算NULL汇总行数

如果count()的括号内指定列名就是不计算NULL值进行汇总

SELECT 
    COUNT(purchase_price)
FROM 
    Product;

执行结果:

COUNT(*) 
--------
6

COUNT函数的结果根据参数的不同而不同。COUNT(*)会得到包含NULL的数据
行数,而COUNT(<列名>)会得到NULL之外的数据行数。

2. 对表进行分组

对数据进行分组统计的时候需要用到 GROUP BY 进行分组,GROUP BY 子句就像切蛋糕那样将表进行了分组。在GROUPBY 子句中指定的列称为聚合键或者分组列。由于能够决定表的切分方式,所以是非常重要的列。

GROUP BY 语法规则

SELECT <列名1>, <列名2>, <列名3>, ……
FROM <表名>
GROUP BY <列名1>, <列名2>, <列名3>, ……;

例如:分别统计每个类别的的商品有多少条数据

SELECT
    product_type,
    COUNT(*) 
FROM
    product 
GROUP BY
    product_type 

执行结果:

product_type | count
-------------|------
衣服         | 2
办公用品     | 2
厨房用具     | 4

GROUP BY 函数表示对相同的数据进行一个分组的汇总,本例中因为重复的有三种情况,所以查询的结果有三行。

每一种类别有不同或者相同的数据,所以要进行一个按组别的显示数据


image.png

子句的书写顺序(暂定)

  1. SELECT → 2. FROM → 3. WHERE → 4. GROUP BY

2.1 聚合键中包含NULL的情况

如果被分组的列包含null值分组会怎么显示呢?

例如:分别统计每个金额有多少条数据?

SELECT
    purchase_price,
    COUNT(*) 
FROM
    product 
GROUP BY
    purchase_price

执行结果:

purchase_price | count
----------------+-------
    | 2 -- 有两项都为空值
320 | 1
500 | 1
5000 | 1
2800 | 2
790 | 1

说明有null值的情况下,显示为空

2.2 有WHERE的情况进行GROUP BY分组

使用GROUP BY 的句子中也可以使用WHERE

SELECT <列名1>, <列名2>, <列名3>, ……
FROM <表名>
WHERE
GROUP BY <列名1>, <列名2>, <列名3>, ……;

像这样使用WHERE 子句进行汇总处理时,会先根据WHERE 子句指定的条件进行过滤,然后再进行汇总处理

SELECT purchase_price, COUNT(*)
FROM Product
WHERE product_type = '衣服'
GROUP BY purchase_price;

执行结果:

purchase_price | count
---------------+------
500            | 1
2800           | 1

同时使用GROUP BY 和 WHERE 的情况下句子的执行顺序为:
FROM → WHERE → GROUP BY → SELECT

3 聚合函数与GROUP BY 常见错误

3.1 常见错误 使用聚合函数时 SELECT 中书写多余列

在使用COUNT 这样的聚合函数时,SELECT 子句中的元素有严格的限制。实际上,使用聚合函数时,SELECT 子句中只能存在以下三种元素。

  • 常数
  • 聚合函数
  • GROUP BY 中指定的列(也指聚合键
    常数就是指常量值,数字或者字符串等。聚合函数就是count、sum之类的。最容易出问题的是写上了聚合键以外的列名。

MySQL除外,写上其它列名也可以执行

示例:根据进货金额分组商品

SELECT product_name, purchase_price, COUNT(*)
FROM Product
GROUP BY purchase_price;
image.png

原因是进货单价为2800的商品有两个,数据库不知道应该取哪一个好。

3.2 在GROUP BY子句中写了列的别名

这也是一个非常常见的错误。SELECT 子句中的项目可以通过AS 关键字来指定别名。但是,在GROUP BY 子句中是不能使用别名的。

示例:GROUP BY子句中错误使用别名

SELECT product_type AS pt, COUNT(*)
FROM Product
GROUP BY pt;

这个句子出错的原因是因为SQL执行顺序的原因。之前有介绍过DBMS是先执行
GROUP BY 再执行 SELECT 句子所以在 SELECT 中设置的别名不生效

需要注意的是,虽然这样的写法在PostgreSQL和MySQL都不会发生执行错误,但是这并不是通常的使用方法

3.3 在WHERE子句中使用聚合函数

最后要介绍的是初学者非常容易犯的一个错误。我们还是先来看一下之前提到的按照商品种类(product_type 列)对表进行分组,计算每种商品数据行数的例子吧。

示例:按照商品种类进行汇总

SELECT
    product_type,
    COUNT(*) 
FROM
    product 
GROUP BY
    product_type 

执行结果:

product_type | count
-------------|------
衣服         | 2
办公用品     | 2
厨房用具     | 4

如果有个问题,在分类好的数据中查找汇总数为2的种类,该怎么写SQL语句呢?
初学者容易犯的错误就是在 WHERE 中直接添加聚合函数。

示例:WHERE中直接使用聚合函数

SELECT product_type, COUNT(*)
FROM Product
WHERE COUNT(*) = 2  -- 错误
GROUP BY product_type;

执行结果:

ERROR: 不能在WHERE子句中使用聚合
行 3: WHERE COUNT(*) = 2

实际上,只有SELECT 子句和HAVING 子句(以及之后将要学到的ORDER BY 子句)中能够使用COUNT 等聚合函数。并且,HAVING 子句可以非常方便地实现上述要求。

只有SELECT子句和HAVING子句(以及ORDER BY子句)中能够使用聚合函数。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,667评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,361评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,700评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,027评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,988评论 5 361
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,230评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,705评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,366评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,496评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,405评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,453评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,126评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,725评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,803评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,015评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,514评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,111评论 2 341

推荐阅读更多精彩内容

  • (一)几个数据库相关的概念 1.数据库 数据库: 保存有组织数据的容器。 数据的所有存储、检索、管理和处理实际上是...
    快乐的小飞熊阅读 511评论 0 1
  • 引出 •请思考如下问题? –查询所有员工的每个月工资总和,平均工资? –查询工资最高和最低的工资是多少? –查询公...
    C_cole阅读 7,274评论 0 3
  • 这一篇最主要是记录下命令,方便以后查找 使用Mysql 创建数据库 create database mysql_t...
    Treehl阅读 569评论 0 0
  • 1. 了解SQL 1.1 数据库基础 ​ 学习到目前这个阶段,我们就需要以某种方式与数据库打交道。在深入学习MyS...
    锋享前端阅读 1,032评论 0 1
  • 1.函数的基本使用 //习题 #include void chline(int i,int j,int (*arr...
    王子言_853c阅读 121评论 0 0