【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來達到相同效果. 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM