SQL 语句继续学习之记录二

三, 聚合与排序

对表进行聚合查询,即使用聚合函数对表中的列进行合计值或者平均值等合计操作。

通常,聚合函数会对null以外的对象进行合计。但是只有count 函数例外,使用count(*) 可以查出包含null在内的全部数据行数。

使用distinct 关键字删除重复值。

1,聚合函数之常见的5个聚合函数

count:计算表中的记录数(行数)

SUM:计算表中数值列的数据合计值

AVG:计算表中数值列的数据平均值

MAX:求出表中任一列中数据的最大值

MIN:求出表中任意列中数据的最小值

如上,用于合计的函数称为聚合函数或者集合函数。所谓聚合,就是将多行汇总为一行。实际上,所有的聚合函数都是这样,输入多行输出一行

1)

a, 如下,我们要获取如下原始数据表中全部数据的行数。

如上,一共有8行数据,所以我们获取到的结果应该是8.

如下 count(*) 中的 * 表示全部列

b, 计算null以外数据的行数

如上,查询的是全部数据(所有列的)行数,但是如果想要查询某个列(比如该列可能存在null 数据) 的行数,该怎么做呢?

比如想得到shiire_tanka 列(进货单价)中非空行数的列,,可以通过将对象列设定为参数来实现

Note:

Count 函数的结果根据参数不同而不同。count(*)会得到该表格包含null数据的所有行数,而count(某个列名)得到的是该列中,除了null之外的数据的行数。

Count 函数也是唯一一个可以以星号 * 为参数的函数,

  1. 计算合计值

例如,我们需要计算销售单价的合计值,即销售单价列,所有数值加起来的总和。

1000 + 4000 + 3000 + 6800 + 500 + 880 + 100 = 16280

Note: 之前我们提到,含有null 的算术运算符中,如果数据含有null,则最终运算结果为null,但如上,最终结果并不为null,而是我们日常生活中所理解的正常的数值。其原因为,聚合函数,除了count 函数外,其他几个聚合函数在最终计算时都会将null 数据提前排除在外。因此不会看到null的结果,这也证明我们之前的描述的正确性。 所谓count函数例外,是说count在参数为星号 * 时,会将null结果计算在内。

3)计算平均值

如我们要获取销售单价的平均值

注意,如上,hanbai_tanka 结果值是16280,如果按照8行为除数,结果应该是2035,但现在的结果是2325.7143, 是因为该数据的计算是 16280 除以 7 得到的结果,也就是说,计算平均值时,avg 函数会将null 数据所在的行排除掉,计算非null数据的总值,同时将非null数据的行数作为除数。

针对上述提到的点,需要特别注意,如果我们需要将null 作为0 进行计算,具体的实现方式需要参考后面的学习。暂时性放弃讲解,可此处留个记录,后续会详细讲述。

4)计算最大值和最小值

想要计算出多条记录中的最大值或最小值,可以分别使用MAX 和 MIN 函数

例如计算销售单价的最大值和进货单价的最小值。

如下,我们获取到了销售单价的最大值和进货单价的最小值

注意:MAX 和 MIN 函数和 SUM/AVG函数有一点区别,即SUM/AVG 函数只能对数值类型的列使用,而 MAX 和 MIN 函数原则上可以适用于任何数据类型的列。例如,我们可以对日期列进行大小值的获取

note: MAX 和 MIN 函数适用于任何数据类型的列,即只要能进行排序的数据,就肯定有最大值和最小值,也就能使用这两个函数,但是需要注意的是,'排序',需要注意是否是字符串等特殊类型,因为字符串排序是要按照数据字典来排序,比如之前 "1","22","3","225"等 字符串排序时,3要比22 大。 另外对与日期和字符串类型数据来说,能够使用MAX/MIN 这两个函数,但不能使用SUM/AVG函数,因为对日期和字符串来说,合计值和平均值均没有实际意义。

即MAX/MIN 函数几乎适用于所有数据类型的列,但SUM/AVG函数只适用于数值类型的列。

5)使用聚合函数删除重复值(关键字distinct)

在之前shohin表中看到,商品种类和日期的数据中,存在多行数据相同的情况

如果我们想要计算出商品种类的个数,怎么做呢? 即删除重复数据,然后再计算数据行数。

note: distinct 必须写在括号中,是因为必须要在计算行数之前删除shohin_bunrui 列中的重复数据。如果不加括号,distinct 需要放在第一列的钱买呢,则如下就会先计算出数据行数,然后再删除重复数据,结果会得到shohin_bunrui列的所有行数,即8

假设我们再增加一个查询列,比如日期这种有重复行的列,结果会如何呢?

如下

复制代码
org.jkiss.dbeaver.model.sql.DBSQLException: SQL Error [1140] [42000]: In aggregated query without GROUP BY, expression #2 of SELECT list contains nonaggregated column 'shop.shohin.torokubi'; this is incompatible with sql_mode=only_full_group_by
	at org.jkiss.dbeaver.model.impl.jdbc.exec.JDBCStatementImpl.executeStatement(JDBCStatementImpl.java:133)
	at org.jkiss.dbeaver.ui.editors.sql.execute.SQLQueryJob.executeStatement(SQLQueryJob.java:582)
	at org.jkiss.dbeaver.ui.editors.sql.execute.SQLQueryJob.lambda$1(SQLQueryJob.java:491)
	at org.jkiss.dbeaver.model.exec.DBExecUtils.tryExecuteRecover(DBExecUtils.java:190)
	at org.jkiss.dbeaver.ui.editors.sql.execute.SQLQueryJob.executeSingleQuery(SQLQueryJob.java:498)
	at org.jkiss.dbeaver.ui.editors.sql.execute.SQLQueryJob.extractData(SQLQueryJob.java:934)
	at org.jkiss.dbeaver.ui.editors.sql.SQLEditor$QueryResultsContainer.readData(SQLEditor.java:3928)
	at org.jkiss.dbeaver.ui.controls.resultset.ResultSetJobDataRead.lambda$0(ResultSetJobDataRead.java:123)
	at org.jkiss.dbeaver.model.exec.DBExecUtils.tryExecuteRecover(DBExecUtils.java:190)
	at org.jkiss.dbeaver.ui.controls.resultset.ResultSetJobDataRead.run(ResultSetJobDataRead.java:121)
	at org.jkiss.dbeaver.ui.controls.resultset.ResultSetViewer$ResultSetDataPumpJob.run(ResultSetViewer.java:5140)
	at org.jkiss.dbeaver.model.runtime.AbstractJob.run(AbstractJob.java:105)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
Caused by: java.sql.SQLSyntaxErrorException: In aggregated query without GROUP BY, expression #2 of SELECT list contains nonaggregated column 'shop.shohin.torokubi'; this is incompatible with sql_mode=only_full_group_by
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
	at com.mysql.cj.jdbc.StatementImpl.executeInternal(StatementImpl.java:763)
	at com.mysql.cj.jdbc.StatementImpl.execute(StatementImpl.java:648)
	at org.jkiss.dbeaver.model.impl.jdbc.exec.JDBCStatementImpl.execute(JDBCStatementImpl.java:330)
	at org.jkiss.dbeaver.model.impl.jdbc.exec.JDBCStatementImpl.executeStatement(JDBCStatementImpl.java:131)
	... 12 more

提示sql 都有错误。

为何呢? 后面再做分析,暂时放在这儿

为了测试distinct 参数,我稍微修改了一下db 中打孔器的价格,从null 改为了500

如上,distinct 可以做count 函数的参数,其实,distinct也可以做其他所有聚合函数的参数,比如如下sql,我们可以尝试获取销售单价在有distinct参数和无distinct参数时的值差别

如上,都是计算销售单价的合计值,但这两个最终的结果却不同,为何呢?

因为在销售单价这一列中,有2个相同值 500 元。上述查询中,

SUM(hanbai_tanka) 是直接查询该列所有的数值加在一起的和,而SUM(distinct hanbai_tanka) 的查询逻辑是,先将该列中重复的数据去除,然后计算数值的总和。因此,上面的查询为

SUM(hanbai_tanka) = 1000 + 500 +4000 +3000 + 6800 + 500 + 880 + 100 =16780

SUM(distinct hanbai_tanka) = 1000 + 500 + 4000 + 3000 + 6800 + 880 +100 =16280

2, 对表进行分组

使用group by 子句可以像切蛋糕那样将表进行分割。通过使用聚合函数 和group by 子句,可以根据"商品种类" 和 "登记日期" 等将表分割后再进行聚合

聚合键中包含null时,在结果中会以"不确定" 行(空行)的形式表现出来

使用聚合函数和group by 子句时需要注意以下4点,

a 只能写在select 子句中

b, group by 子句中不能使用select子句中列的别名

c, group by 子句的聚合效果是无序的

d, where 子句中不能使用聚合函数

1)group by 子句

之前学习记录中,我们看到的聚合函数的使用方法中,无论是否包含null,无论是否删除了重复数据,都是针对表中的所有数据进行的聚合处理。而接下来的这里,我们先把表分成几组,然后再进行聚合处理。也就是按照"商品种类" 、"登记日期"等进行聚合。

1> 使用group by 子句进行聚合的sql 格式

select <列名1>, <列名2 >, <列名3>

from < 表名>

group by < >, < >, <>

例如,我们按照商品种类来统计一下数据行数(=商品数量)

如上,商品种类一共有3种,衣服,办公用品,厨房用具

在此,我们需要分析一个问题,即group by 有和没有的区别。 如果没有group by 子句,聚合函数count(*) 相当于把整个表作为一个group,将该组中的数据行数进行计算。但是如果使用了group by, 系统会先把整个表按照聚合键(group by 子句中指定的列称为聚合键或者分组列)来切分成多个组,之后count 对每个组中的数据行数进行计算。

实际上,group by子句也和select子句一样,可以通过逗号分隔指定多列

如下,我们做测试如图

2> 使用where 子句时 Group by 的执行结果

在使用了group by 子句的select语句中,也可以正常使用where 子句。子句的排列顺序如图

使用where 子句和group by 子句进行聚合处理

select <列名1>, <列名2>,<列名3>

from <表名>

where

group by <列名1>,<列名2>,<列名3>

但请注意: group by 和 where 子句并用时,select语句的执行顺序如下所示

From ------> where ------> group by------>select

像这样使用where子句进行聚合处理时,会先根据where子句制定的条件进行过滤,然后再进行聚合处理。 如下

3> 与聚合函数和group by子句有关的常见错误

a, 常见错误问题1------在select子句中书写了多余的列

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

(1)常数

(2)聚合函数

(3)group by 子句中指定的列名(也就是聚合键)

如上面记录的一个错误,此处由于select语句中使用了count这样的聚合函数,所以在select语句中不能出现类似torokubi 这样的shohin 表中其他的数据列,这样sql 将无法执行。

相关推荐
MowenPan199531 分钟前
高等数学 9.1多元函数的基本概念
笔记·学习·高等数学
.Shu.1 小时前
Mysql InnoDB 底层架构设计、功能、原理、源码系列合集【五、InnoDB 高阶机制与实战调优】
数据库·mysql
新法国菜2 小时前
MySql知识梳理之DDL语句
数据库·mysql
DarkAthena3 小时前
【GaussDB】全密态等值查询功能测试及全密态技术介绍
数据库·gaussdb
ShawnLeiLei4 小时前
2.3 Flink的核心概念解析
数据库·python·flink
今天也要学习吖4 小时前
Azure TTS Importer:一键导入,将微软TTS语音接入你的阅读软件!
人工智能·学习·microsoft·ai·大模型·aigc·azure
石皮幼鸟4 小时前
数据完整性在所有场景下都很重要吗?
数据库·后端
楼田莉子5 小时前
C++算法学习专题:滑动窗口
开发语言·数据结构·c++·学习·算法·leetcode
小晶晶京京5 小时前
day38-HTTP
网络·网络协议·学习·http
炸膛坦客5 小时前
C++ 学习与 CLion 使用:(四)常量和变量,包括字面常量和符号常量
开发语言·c++·学习