表名: 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)的区别的更多相关文章

  1. 【MySQL】汇总数据 - avg()、count()、max()、min()、sum()函数的使用

    第12章 汇总数据 文章目录 第12章 汇总数据 1.聚集函数 1.1.AVG()函数 avg() 1.2.COUNT()函数 count() 1.3. MAX()函数 max() 1.4.MIN() ...

  2. [MongoDB]count,gourp,distinct

    摘要 上篇文章介绍了CRUD的操作,会了这些,基本上可以完成很多工作了.但如果遇到统计类的操作,那么就需要学习下本篇的内容了. 相关文章 [MongoDB]入门操作 [MongoDB]增删改查 cou ...

  3. 【优化】COUNT(1)、COUNT(*)、COUNT(常量)、COUNT(主键)、COUNT(ROWID)、COUNT(非空列)、COUNT(允许为空列)、COUNT(DISTINCT 列名)

    [优化]COUNT(1).COUNT(*).COUNT(常量).COUNT(主键).COUNT(ROWID).COUNT(非空列).COUNT(允许为空列).COUNT(DISTINCT 列名) 1. ...

  4. Django学习路17_聚合函数(Avg平均值,Count数量,Max最大,Min最小,Sum求和)基本使用

    使用方法: 类名.objects.aggregate(聚合函数名('表的列名')) 聚合函数名: Avg 平均值 Count数量 Max 最大 Min 最小 Sum 求和 示例: Student.ob ...

  5. Oracle 中count(1) 和count(*) 的区别

    count()与count(*)比较: 如果你的数据表没有主键,那么count()比count(*)快 如果有主键的话,那主键(联合主键)作为count的条件也比count(*)要快 如果你的表只有一 ...

  6. 【MySQL】技巧 之 count(*)、count(1)、count(col)

    只看结果的话,Select Count(*) 和 Select Count(1) 两着返回结果是一样的. 假如表沒有主键(Primary key), 那么count(1)比count(*)快,如果有主 ...

  7. 关于count(1) 和 count(*)

    Q:What is the difference between count(1) and count(*) in a sql queryeg.select count(1) from emp; an ...

  8. select count(*)和select count(1)的区别 (转)

    A 一般情况下,Select Count (*)和Select Count(1)两着返回结果是一样的 假如表沒有主键(Primary key), 那么count(1)比count(*)快, 如果有主键 ...

  9. 【转载】Oracle 中count(1) 、count(*) 和count(列名) 函数的区别

    1)count(1)与count(*)比较: 1.如果你的数据表没有主键,那么count(1)比count(*)快2.如果有主键的话,那主键(联合主键)作为count的条件也比count(*)要快3. ...

随机推荐

  1. 修改字段字符集 mysql 修改 锁表 show processlist; 查看进程 Waiting for table metadata lock

    ALTER TABLE `question` MODIFY COLUMN `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unico ...

  2. TA-Lib中文文档(二):talib安装

    安装 使用pip安装 PyPI: $ pip install TA-Lib Or checkout the sources and run setup.py yourself: $ python se ...

  3. SQL基础--查询之四--集合查询

    SQL基础--查询之四--集合查询

  4. kubernetes实战(八):k8s集群安全机制RBAC

    1.基本概念 RBAC(Role-Based Access Control,基于角色的访问控制)在k8s v1.5中引入,在v1.6版本时升级为Beta版本,并成为kubeadm安装方式下的默认选项, ...

  5. MySQL的知识海洋

    第一篇:初识数据库 第二篇:库操作 第三篇:表操作 第四篇:数据操作 第五篇:视图.触发器.存储过程.函数.事物与数据库锁 第六篇:索引原理与慢查询优化 第七篇:pymysql(用python连接以及 ...

  6. python练习汇总

    1.99乘法表 """ 题目:输出 9*9 乘法口诀表. """ for i in range(1, 10): print () for j ...

  7. elasticsearch-hadoop使用

    elasticsearch-hadoop是一个深度集成Hadoop和ElasticSearch的项目,也是ES官方来维护的一个子项目,通过实现Hadoop和ES之间的输入输出,可以在Hadoop里面对 ...

  8. AE开发的一个想法

    基于字典进行GIS图形进行编辑. 图层信息 大类别 字典项(属性字段) 居民点 控制点 GPS控制点 线状道路 铁路 省道 国道 一般公路 名称 长度 等级 备注 线状水系 面状道路 面状水系 湖泊 ...

  9. Cardano(ADA), EOS, RChain(RHOC), Aeternity(AE) 都是极其好的币

    从区块链的基础知识出发,研究ETH和EOS的区别 免责声明:EOS目前还在开发中,我们对此项目的一些理解可能会改变.而且,我并不是以太坊开发者,而只是一个喜欢区块链的爱好者.请牢记这两点,请把下面的内 ...

  10. SLG手游Java服务器的设计与开发——网络通信

    文章版权归腾讯GAD所有,禁止匿名转载:禁止商业使用:禁止个人使用. 一.前言 上文分析了我们这款SLG的架构,本章着重讲解我们的网络通信架构,由上文的功能分析我们可以得知,游戏的所有功能基本上属于非 ...