【hive】cube和rollup函數


cube

  • 數據立方體(Data Cube),是多維模型的一個形象的說法.(關於多維模型這里不講述,在數據倉庫設計過程中還挺重要的,有興趣自行查閱)
  • 立方體其本身只有三維,但多維模型不僅限於三維模型,可以組合更多的維度
  • 為什么叫數據立方體?
    • 一方面是出於更方便地解釋和描述,同時也是給思維成像和想象的空間;
    • 另一方面是為了與傳統關系型數據庫的二維表區別開來

下圖為數據立方體的形象圖
數據立方體

  • 其實並不用把cube理解得很高大上,只要理解為分別按照不同維度進行聚合.
  • hive中也有cube函數,可以實現多個任意維度的查詢
    • cube(a,b,c)則首先會對(a,b,c)進行group by,
    • 然后依次是(a,b),(a,c),(a),(b,c),(b),(c),最后在對全表進行group by,他會統計所選列中值的所有組合的聚合
    • 用cube函數就可以完成所有維度的聚合工作.

語法

select col1,col2,col3,col4, --維度字段
         count(user_id),  --聚合字段
         GROUPING__ID, --聚合選取的組號(二進制表示,但是這里打印出來的是十進制)
         rpad(reverse(bin(cast(GROUPING__ID AS bigint))),4,'0') --對其二進制化就能明白了,注意中間是兩個下划線,因為在反轉的時候會把末尾的0去掉,需要用rpad補充至維度個數
from table 
group by col1,col2,col3,col4  --維度字段都要出現在group by中,這里不能使用1,2,3,4代替
with cube; --使用cube函數
  • 如果我們想要手動實現cube函數就需要把所有維度的聚合都用union all來匯總.
  • 可以說cube函數方便了用戶的使用.
  • 但是我並不用知道所有維度的聚合,我就想要col1,(col2,col3)的怎么辦?

grouping sets

  • 當不需要cube將所有維度都列出來的時候,當只需要部分維度的時候
  • 可以使用grouping sets來進行決定聚合那些維度

語法

select col1,col2,col3, --維度字段
         count(user_id),  --聚合字段
         GROUPING__ID, --聚合選取的組號(二進制表示,但是這里打印出來的是十進制)
        rpad(reverse(bin(cast(GROUPING__ID AS bigint))),3,'0') --對其二進制化就能明白了,注意中間是兩個下划線,注意中間是兩個下划線,因為在反轉的時候會把末尾的0去掉,需要用rpad補充至維度個數
from table 
group by col1,col2,col3  --維度字段都要出現在group by中,並不能省略暫時不用到的字段,這里不能使用1,2,3,4代替
grouping sets(col1,(col2,col3)); --使用grouping sets來代替with cube
  • 注意:當使用grouping sets()進行指定維度聚合的時候,僅僅聚合你給出的維度組合,並不會自動幫你組合維度.
    • 例如 grouping sets(col1,(col2,col3)) 只聚合col1維度,(col2,col3)維度.
    • 並不會自動聚合(col1,col2,col3)維度

rollup

  • rullup函數是cube的子集,以最左側維度為主,按照順序依次進行聚合.
  • 例如聚合的維度為 col1,col2,col3 使用rollup聚合的字段分別為 col1,(col1,col2),(col1,col3),(col1,col2,col3)

語法

select col1,col2,col3,col4, --維度字段
         count(user_id),  --聚合字段
         GROUPING__ID, --聚合選取的組號(二進制表示,但是這里打印出來的是十進制)
         rpad(reverse(bin(cast(GROUPING__ID AS bigint))),4,'0') --對其二進制化就能明白了,注意中間是兩個下划線,注意中間是兩個下划線,因為在反轉的時候會把末尾的0去掉,需要用rpad補充至維度個數
from table 
group by col1,col2,col3,col4  --維度字段都要出現在group by中,這里不能使用1,2,3,4代替
with rollup; --使用rollup函數

如何查看根據什么維度聚合呢?

select user_type,sales, --維度
         count(user_id) as pv, --聚合字段
         grouping__id,
         rpad(reverse(bin(cast(GROUPING__ID AS bigint))),2,'0') as sign --grouping__id逆序
from user_info
group by user_type,sales
with cube;

查詢結果如下

user_type sales pv grouping__id sign
NULL NULL 10 0 00
old NULL 3 1 10
new NULL 7 1 10
old 3 1 3 11
old 2 1 3 11
old 1 1 3 11
new 6 1 3 11
new 5 2 3 11
new 3 1 3 11
new 2 1 3 11
new 1 2 3 . 11
  • 上面是使用cube函數聚合后的數據
  • 可以根據 GROUPING__ID 的二進制表示形式(反向)直接看出.
    • 這里使用聚合的維度有user_type和sales兩個維度,如果使用當前維度,對應bin(grouping__id)數字為1
    • 例如 第二行數據的 10 -> 使用了user_type維度,沒使用sales
  • 可以通過聚合后的數據看出
    • 當改字段為NULL的時候,說明沒有使用該字段維度.
    • 例如 第二行數據 old NULL -> 使用了user_type維度,沒使用sales


免責聲明!

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



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