SQL学习之HAVING过滤分组
1、SQL除了能用Group By分组数据之外,SQL还允许过滤分组,规定包括那些分组,排除那些分组。例如,你可能想要列出至少有两个订单的所有顾客。为此,必须基于完整的分组而不是个别的行进行过滤。
基于上面的例子,我们第一时间想到的是通过使用WHERE来过滤数据,拿到我们想要的结果,但是在这个列子中WHERE不能完成任务,因为WHERE过滤指定的是行,而不是分组。事实上,WHERE没有分组的概念。
因此,SQL提供了专门用来过滤分组的类似与WHERE子句的子句,HAVING子句,事实上,几乎所有类型的WHERE子句都可以用HAVING来代替。唯一的差别是,WHERE过滤行数据,HAVING过滤分组数据。
如下代码:
select * from dbo.T_Unit_Equipment
现在有一个报表系统,需要展示每个单位,拥有每台设备的数量,这个时候用WHERE很麻烦(前提是数据量比较少的情况下),下面是解决代码:
select UnitId,EquipmentName,COUNT(*) as Equipments from dbo.T_Unit_Equipment group by UnitId,EquipmentName order by UnitId ASC
ok,完成需求!
现在,改变需求,现在需要检索出每家单位拥有的同一种设备大于等于2的记录,下面是解决代码:
select UnitId,EquipmentName,COUNT(*) as Equipments from dbo.T_Unit_Equipment group by UnitId,EquipmentName HAVING COUNT(*)>=2 order by UnitId ASC
ok,完成需求!
上面的代码通过UnitId,EquipmentName两个字段进行分组,然后SELECT语句检索出UnitId,EquipmentName,以及Equipments(Equipments在这里是一个计算字段,通过COUNT()函数计算出每个分组的总记录数),然后HAVING子句告诉SELECT语句只检索出所有分组中的总记录数大于等于2的分组记录。这里的COUNT(*)>=2过滤了每家单位所拥有的同一种设备小于2的分组!
2、WHERE和HAVING的差别:
(1)WHERE在数据分组前进行过滤,HAVING在数据分组之后进行过滤,这是个很重要的区别,WHERE排除的行不包括在分组中。这可能会改变计算值,从而影响HAVING子句中基于这些值的过滤掉的分组,根据这个差别,我们可以确定WHERE子句和Group By子句的位置:WHERE子句会在数据分组之前,对行数据进行过滤。
(2)HAVING与WHERE非常类似,如果不指定Group By,则大多数DBMS会同等的对待他们,不过你自己要区分这一点,使用HAVING时应该结合Group By子句,而WHERE子句用于标准的行级数据过滤
下面通过一个例子来了解HAVING子句与WHERE子句的差别
select * from dbo.T_Unit_Equipment
现在需要检索出每家单位拥有的同一种设备大于等于2的记录,前提是设备必须有维护人员(对应表中的Person列值不能为空),下面是解决代码:
select UnitId,EquipmentName,COUNT(*) as Equipments from dbo.T_Unit_Equipment where Person!='' group by UnitId,EquipmentName HAVING COUNT(*)>=1 order by UnitId ASC
ok,完成需求!
where 过滤了Person=''的列值,然后Group By在对剩余的数据进行分组,之后HAVING子句进行分组过滤!
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Spring Boot Admin实现服务健康预警
- 除了FastJson,你也应该了解一下Jackson(二)
- 除了FastJson,你也应该了解一下Jackson(一)
- JavaScript性能优化总结
- Spring Boot2+Resilience4j实现容错之Bulkhead
- [译]高性能缓存库Caffeine介绍及实践
- 云原生时代高性能Java框架—Quarkus(一)
- 云原生时代高性能Java框架—Quarkus(二)
- 使用TypeScript积累自己的类库
- 在Egret项目中使用protobuf
- JavaScript原型与继承
- 当TKE遇上Coding, 业务如何实现快速迭
- cocos creator 1.x透明渐变效果实现
- Cocos Creator 2.x透明渐变效果实现
- Themeleaf通过ajax局部更新