天天看點

mysql sumif distinct_【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())來進行篩選統計,但是效果并沒有達到,出現的結果如下

2018090116737 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;

結果如下

2018090116737 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不執行

mysql sumif distinct_【hive】count() count(if) count(distinct if) sum(if)的差別

我們通過模拟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;

結果如下

2018090116737 260

sum(if)隻試用于單個條件判斷,如果篩選條件很多,我們可以用sum(case when then else end)來進行多條件篩選

注意,hive中并沒有sum(distinct col1)這種使用方式,我們可以使用sum(col) group by col來達到相同效果.