理解group by语义

个人认为sql中的group by和join是两大难点,因为它们转换了原来的表结构,group把表按某些字段统计缩小,join则使用笛卡尔积将多个表连接展开(关于表的连接,请参看深入理解SQL表连接(join),这篇文章以一个非常有趣的角度,带你彻底理解SQL表连接的本质)

咱们回到group by,顾名思义group即为分组,即将原来的一整块数据分成几小块。分组是聚合的前提,聚合是在每个分组内进行一些统计,如在分组内的最大值,最小值,平均值,个数等。

未分组时查询返回的行直接与数据库表中的行对应,分组后分为多少组这个查询就会返回多少条记录,返回的记录中只能包含分组字段和在这个分组上的聚合操作的值(MySQL是例外见后面)

一般形式为:语法为:select t.sex, count(t.id) as cnt group by sex having cnt>2
查询中有三种字段:
查询字段:在select中出现的表中的字段
聚合字段:对表中的字段施加了聚合函数后形成的字段
分组字段:group by后的字段

无分组字段时

sql允许无分组字段,即无group by直接在select中用各种聚合函数,这时表示整块数据为一个分组(单分组),聚合操作则是在整块全局上进行聚合,表示为本查询中所有记录的最大值,最小值,平均值,个数等
如果没有分组字段的聚合,则select后的字段只能全部都是带聚合的,不能直接是字段名否则Orcle会报错:ORA-00937: not a single-group group function(MySQL是个例外后面详述)

MySQL的坑

MySQL有一个让人不解的地方:在聚合查询中select可以出现非分组字段,语义上group by后的结果已经进行了分组变换,此时的数据均应对应于分组而不再是原表记录,在一个分组语义的记录里加入一个表的字段,语义上不太严谨,实际上MySQL会将非分组字段随便取一个值,不得不说算一个坑
比如下面的查询Oracle报错而MySQL不报错
select id, count(t.id) from
(
select 1 as id, 2 as age, 'F' as sex from dual union
select 2 as id, 2 as age, 'M' as sex from dual union
select 3 as id, 3 as age, 'F' as sex from dual union
select 4 as id, 4 as age, 'M' as sex from dual 
)t
在MySQL中返回
1 4
该查询是单分组查询,4是总的记录条数没有问题,此时1是什么意思呢?它和计数有什么关系呢?

*MySQL后面意识到这会导致很多潜在的问题,因此在高版本中对此问题进行了修复,即不再允许在select中出现非group的字段

对null的处理

count(*)统计包含null在内的行数,count后面跟上字段名则表示统计这个字段非null的行数

聚合函数后面可以跟一个复合表达式,如多个字段相加,复合时如果其中一个字段为null则整个表达式为null,比如统计两个字段都非null的行数,可以count(f1+f2)

count,avg,sum后面跟上字段名时如果为null值将会忽略,比如计算平均值时null的那一行并不会记入总行数

如果带有group by则select后的字段要么是分组字段要么是聚合字段(MySQL仍然可以出现非分组字段)

关于having

与where不同的是having在group后进行进行过滤,where在group前进行过滤其写在group关键字前,having后过滤的字段可以是分组字段或聚合字段如:
select sex, count(*) as cnt having sex='F'
select sex, count(*) as cnt having cnt>1

小技巧

有时需要测试sql语法但又觉得创建表麻烦,可以使用创建一个临时表,如下:
select id, count(t.id) from
(
select 1 as id, 2 as age, 'F' as sex from dual union
select 2 as id, 2 as age, 'M' as sex from dual union
select 3 as id, 3 as age, 'F' as sex from dual union
select 4 as id, 4 as age, 'M' as sex from dual 
)t

深入理解sql分组查询(group by)相关推荐

  1. sql分组查询group by结合count,sum统计语句的实现(附带sql详细分析步骤)

    日常写代码经常会遇到数据统计的业务场景,分组查询 group by 结合 count 和 sum 的复杂语句写起来容易令人头大,在这里分享两个比较复杂的统计场景,提供详细分析思路和最终sql语句,希望 ...

  2. SQL语句之分组查询--GROUP BY(group by)

    SQL语句之分组查询–GROUP BY(group by) 语法 select 聚合函数,列(要求出现在group by的后面)from 表where 筛选条件group by 分组的列表order ...

  3. SQL数据库——分组查询GROUP BY

    一.分组查询GROUP BY 1.语法 SELECT (列名) as '自由命名' , COUNT(*) as '自由命名'; from (表名); GROUP BY (列名); 2. * 号里可以为 ...

  4. sql语法基础,sql分组查询

    01分组查询–group by 格式: SELECT 列名1,列名2,... FROM 表名 GROUP BY 列名1,列名2.... 例一,按照商品种类统计一下行数 SELECT product_t ...

  5. oracle分组聚合查询,Oracle中分组查询group by用法规则解析

    本篇文章小编给大家分享一下Oracle中分组查询group by用法规则解析,文章介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. Oracle中group by ...

  6. SQL分组查询和分页查询[代码+运行结果+讲解]

    文章目录 前言 一.分组查询 二.分页查询 总结 前言 分组查询和分页查询也是开发中用到的对数据库表的查询操作.下述代码都是通过stu表,内容如下图: 一.分组查询         1.查询男同学和女 ...

  7. mysql 分组查询例子_分组查询GROUP BY用法例子详解

    GROUP BY在mysql中是分组查询了,那么你对于GROUP BY有了解多少呢,下面我们来看一篇关于GROUP BY使用例子,具体的细节如下所示. 在SQL中使用GROUP BY来对SELECT的 ...

  8. SQL分组查询后取每组的前N条记录

    本文由 Leon 同学授权发布 这个公众号的关注者除了大部分是 Android 工程师之外还有部分后端以及前端同学,我鼓励也非常欢迎大家来投稿,其实我们并不需要把自己限定在某个领域,多学学其他语言也是 ...

  9. sql分组查询的使用

    理解group by语义 个人认为sql中的group by和join是两大难点,因为它们转换了原来的表结构,group把表按某些字段统计缩小,join则使用笛卡尔积将多个表连接展开(关于表的连接,请 ...

最新文章

  1. .NET 3.5(12) - DLINQ(LINQ to SQL)之事务处理和并发处理
  2. Github火爆的项目,用聪明的方式学习Vim!
  3. 合并单元格两行_Excel合并单元格的麻烦事你都经历了哪些?来一起远离那些麻烦事...
  4. pom.xml文件指定jdk版本号/跳过测试
  5. html页面右侧滚动,HTML5页面点击和左右滑动页面滚动
  6. linux时间轮 Timing-Wheel的实现
  7. VS Code vue 模板
  8. 纵表、横表互转的SQL
  9. javascript动态字母
  10. 论文精读—XGBoost paper
  11. quartz spring 时间配置
  12. DRL实战 : 强化学习在广告点击业务中的应用
  13. MYSQL时间函数之FROM_UNIXTIME
  14. ansys命令流——布尔运算
  15. (附源码)ssm教培管理系统 毕业设计 230932
  16. 峰值信噪比公式_图像峰值信噪比的计算
  17. 服务器mstsc远程桌面,远程桌面工具,详细教您如何使用远程桌面工具mstsc连接远程桌面...
  18. 杨子江gre填空词汇分类整理
  19. 移动端百度点击软件操作方法及常见问题
  20. Caused by: org.springframework.web.client.RestClientException: Error while extracting response for t

热门文章

  1. Java学习之路:少走弯路,就是捷径
  2. Unity3D 开发工具系列 日志系统:输出模块ConsoleAppender
  3. 网络猫只有计算机和机顶盒两个口,光猫为什么有千兆口和百兆口,两个不同的接口?二者有什么区别?...
  4. 个人打地鼠游戏制作流程
  5. oracle ORA-00918 未明确定义列
  6. oracle递归查询详解,[数据库]Oracle递归查询
  7. Docker 镜像上传到私有云和阿里云的超详细图文步骤
  8. .user.ini文件构成的PHP后门(转)
  9. 101-STM32+Air724UG基本控制篇(自建物联网平台)-基础搭建-购买云主机,安装MQTT服务器软件(Linux系统)
  10. 如何将word人名制成表格