【hive】count() count(if) count(distinct if) sum(if)的区别
表名: user_active_day (用户日活表)
表内容:
user_id(用户id) user_is_new(是否新用户 1:新增用户 0:老用户) location_city(用户所在地区) partition_date(日期分区)
需求:
找出20180901至今的xxx地区的用户日活量以及新增用户量
思路:
筛选日期分区和地区,统计user_id的数量为用户日活量,统计user_is_new = 1的数量为新增用户量.
最开始写的hql语句
select partition_date,count(user_id),
count(if(user_is_new = 1, user_id, 0)) --注意新增用户量的统计
from dw.nice_live_dw_user_active_day
where location_city like '%xxx%' and partition_date >= 20180901
group by partition_date;
我们使用count(if())来进行筛选统计,但是效果并没有达到,出现的结果如下
20180901 16737 16737
根本就没有达到筛选的目的,为什么?
这就要从count的机制说起
首先count()是对数据进行计数,说白了就是你来一条数据我计数一条,我不关心你怎么分类,我只对数据计数
每条数据从if()函数出来,还是一条数据,所以count+1
所以count(user_id)跟count(if(user_id))没有任何的区别.
我们稍做修改
select partition_date,count(user_id),
count(distinct if(user_is_new = 1, user_id, 0)) --注意新增用户量的统计,加了distinct去重
from dw.nice_live_dw_user_active_day
where location_city like '%xxx%' and partition_date >= 20180901
group by partition_date;
结果如下
20180901 16737 261
这次看着就像是对了吧,我们加了distinct进行去重
每次来一条数据先过if()然后再进行去重最后统计.但是实际上结果依旧是错误的.
我们来模拟一下筛选统计的过程
我们有这样四条数据
user_id user_is_new
1 1
2 0
3 1
4 0
表中的数据是一条一条遍历的,
(1)当user_id = 1的数据过来的时候,我们先过if函数 user_is_new = 1 ==> count(distinct user_id = 1),
然后我们把user_id = 1进行重复判断,我们用一个模拟容器来模拟去重,
从容器里找user_id = 1的数据,发现没有,不重复,所以通过我们把count+1,然后把user_id = 1的数据放入,用于下条去重
(2)当user_id = 2的数据过来的时候,我们先过if函数 user_is_new = 0 ==> count(distinct 0),
然后我们把0进行重复判断,
从容器里找0的数据,发现没有,不重复,所以通过我们把count+1,然后把0的数据放入,用于下条去重
(3)当user_id = 3的数据过来的时候,我们先过if函数 user_is_new = 1 ==> count(distinct user_id = 3),
然后我们把user_id = 3进行重复判断,
从容器里找user_id = 3的数据,发现没有,不重复,所以通过我们把count+1,然后把user_id = 3的数据放入,用于下条去重
(4)当user_id = 4的数据过来的时候,我们先过if函数 user_is_new = 0 ==> count(distinct 0),
然后我们把0进行重复判断,
从容器里找0的数据,发现重复,是之前user_id = 2的时候过if()转化成0的那条数据,所以count不执行

我们通过模拟count(distinct if)过程发现,在count的时候我们把不符合条件的最开始的那条语句也count进去了一次
导致最终结果比正确结果多了1.
我们在原基础语句上再减去1就是正确的hql语句
其实在日常中我们做分类筛选统计的时候一般是用sum来完成的,符合条件sum+1,不符合条件sum+0
select partition_date,count(user_id),
sum(if(user_is_new = 1, 1, 0)) --用sum进行筛选统计
from dw.nice_live_dw_user_active_day
where location_city like '%xxx%' and partition_date >= 20180901
group by partition_date;
结果如下
20180901 16737 260
sum(if)只试用于单个条件判断,如果筛选条件很多,我们可以用sum(case when then else end)来进行多条件筛选
注意,hive中并没有sum(distinct col1)这种使用方式,我们可以使用sum(col) group by col来达到相同效果.
【hive】count() count(if) count(distinct if) sum(if)的区别的更多相关文章
- 【MySQL】汇总数据 - avg()、count()、max()、min()、sum()函数的使用
第12章 汇总数据 文章目录 第12章 汇总数据 1.聚集函数 1.1.AVG()函数 avg() 1.2.COUNT()函数 count() 1.3. MAX()函数 max() 1.4.MIN() ...
- [MongoDB]count,gourp,distinct
摘要 上篇文章介绍了CRUD的操作,会了这些,基本上可以完成很多工作了.但如果遇到统计类的操作,那么就需要学习下本篇的内容了. 相关文章 [MongoDB]入门操作 [MongoDB]增删改查 cou ...
- 【优化】COUNT(1)、COUNT(*)、COUNT(常量)、COUNT(主键)、COUNT(ROWID)、COUNT(非空列)、COUNT(允许为空列)、COUNT(DISTINCT 列名)
[优化]COUNT(1).COUNT(*).COUNT(常量).COUNT(主键).COUNT(ROWID).COUNT(非空列).COUNT(允许为空列).COUNT(DISTINCT 列名) 1. ...
- Django学习路17_聚合函数(Avg平均值,Count数量,Max最大,Min最小,Sum求和)基本使用
使用方法: 类名.objects.aggregate(聚合函数名('表的列名')) 聚合函数名: Avg 平均值 Count数量 Max 最大 Min 最小 Sum 求和 示例: Student.ob ...
- Oracle 中count(1) 和count(*) 的区别
count()与count(*)比较: 如果你的数据表没有主键,那么count()比count(*)快 如果有主键的话,那主键(联合主键)作为count的条件也比count(*)要快 如果你的表只有一 ...
- 【MySQL】技巧 之 count(*)、count(1)、count(col)
只看结果的话,Select Count(*) 和 Select Count(1) 两着返回结果是一样的. 假如表沒有主键(Primary key), 那么count(1)比count(*)快,如果有主 ...
- 关于count(1) 和 count(*)
Q:What is the difference between count(1) and count(*) in a sql queryeg.select count(1) from emp; an ...
- select count(*)和select count(1)的区别 (转)
A 一般情况下,Select Count (*)和Select Count(1)两着返回结果是一样的 假如表沒有主键(Primary key), 那么count(1)比count(*)快, 如果有主键 ...
- 【转载】Oracle 中count(1) 、count(*) 和count(列名) 函数的区别
1)count(1)与count(*)比较: 1.如果你的数据表没有主键,那么count(1)比count(*)快2.如果有主键的话,那主键(联合主键)作为count的条件也比count(*)要快3. ...
随机推荐
- JavaScript高级程序设计第三版学习笔记(一)之数据类型区分详谈
null.NaN.undefined三者的区别是什么? 在初次接触到JavaScript的时候,傻傻的分不清null.NaN.undefined三者到底区别何在,在实际的项目开发中也因为这个问题而困惑 ...
- socket套接字TCP协议传输-案例测试
术语: 套接字接口:socket,是一个IP地址和一个端口号的组合,套接字可以唯一标识整个Internet中的一个网络进程. TCP连接:一对套接字接口(一个用于接收,一个用于发送)可定义面向连接的协 ...
- Java调用Python脚本并获取返回值
在Java程序中有时需要调用Python的程序,这时可以使用一般的PyFunction来调用python的函数并获得返回值,但是采用这种方法有可能出现一些莫名其妙的错误,比如ImportError.在 ...
- DIY自己的GIS程序(2)——局部刷新
绘制线过移动鼠标程中绘制临时线段防闪烁 参考OpenS-CAD想实现绘制线的功能.希望实现绘制线的过程,在移动线的时候没有闪烁和花屏.但是出现了问题,困扰了2天,前天熬的太晚,搞得现在精力都没有恢复. ...
- 表单(中)-EasyUI Combogrid 组合网格、EasyUI Numberbox 数字框、EasyUI Datebox 日期框、EasyUI Datetimebox 日期时间框、EasyUI Calendar 日历
EasyUI Combogrid 组合网格 扩展自 $.fn.combo.defaults 和 $.fn.datagrid.defaults.通过 $.fn.combogrid.defaults 重写 ...
- Python之迭代器及生成器
一. 迭代器 1.1 什么是可迭代对象 字符串.列表.元组.字典.集合 都可以被for循环,说明他们都是可迭代的. 我们怎么来证明这一点呢? from collections import Itera ...
- JDBC NOTE
JDBC 基本流程: 1. 加载驱动 a. SQLSERVER:Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver&quo ...
- viewport 编写 iPhone Friendly 的 Web 应用程序
在了解到iPhone的一些常见布局法后,我们就可以开始着手编写一个真正能在iPhone上跑的页面了.小声说一句,之前我说要布局讨论完了,要进入交互逻辑开发,后来细心一想发现不行,有些东西不讲的话将会对 ...
- 17初识select
多路复用 select 同时监控多个文件描述符的输入输出 <sys/types.h> <sys/times.h> <sys/select.h> int select ...
- 20145211《网络对抗》逆向及BOF基础实践
逆向及BOF基础实践——又是一年梅落时 一.实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. ...