自連接,窗口函數(sum、avg、max、min)實戰

採用自連接窗口函數兩種方法解題:

求每個用戶截止到每月爲止的當月訪問次數、最大單月訪問次數、累計到該月的總訪問次數。

三個字段的意思:
用戶名,月份,訪問次數

表名visits
字段id, vmonth, pv

數據:
A,2015-01,5
A,2015-01,15
B,2015-01,5
A,2015-01,8
B,2015-01,25
A,2015-01,5
A,2015-02,4
A,2015-02,6
B,2015-02,10
B,2015-02,5
A,2015-03,16
A,2015-03,22
B,2015-03,23
B,2015-03,10
B,2015-03,11

最後結果展示:
結果數據 result-data           (本月和上月比保留最大) (本月累加上月)
用戶	月份		當月訪問次數	   最大訪問次數	        總訪問次數		
A       2015-01		    33		        33		            33
A       2015-02		    10				33					43
A       2015-03		    38				38					81
B       2015-01			30				30					30
B       2015-02			15				30					45
B       2015-03			44				44					89

方法1,自連接

  1. 先求出當月訪問次數

    select id,vmonth,sum(pv) as pv from visits group by id,vmonth;
    

    結果:

    id      vmonth      pv
    A       2015-01 	33
    A       2015-02 	10
    A       2015-03 	38
    B       2015-01 	30
    B       2015-02 	15
    B       2015-03 	44
    
  2. 根據上述語句用CTAS創建兩張表t1和t2,用於自連接。

    select * from v1 join v2 on v1.id = v2.id;
    
    v1                          v2
    A       2015-01		33      A       2015-01 	33
    A       2015-02 	10      A       2015-01 	33
    A       2015-03 	38      A       2015-01 	33
    A       2015-01 	33      A       2015-02 	10
    A       2015-02 	10      A       2015-02 	10
    A       2015-03 	38      A       2015-02 	10
    A       2015-01 	33      A       2015-03 	38
    A       2015-02 	10      A       2015-03 	38
    A       2015-03 	38      A       2015-03 	38
    B       2015-01		30      B       2015-01 	30
    B       2015-02 	15      B       2015-01 	30
    B       2015-03 	44      B       2015-01 	30
    B       2015-01 	30      B       2015-02 	15
    B       2015-02 	15      B       2015-02 	15
    B       2015-03 	44      B       2015-02 	15
    B       2015-01 	30      B       2015-03 	44
    B       2015-02 	15      B       2015-03 	44
    B      2015-03      44      B       2015-03 	44
    
  3. 我們需要v2的月份>=v1的月份,用來後續做v1月份的累加操作。

    create table v3 as 
    select v1.id as v1id,v1.vmonth as v1month,v1.pv as v1pv,
    v2.id as v2id,v2.vmonth as v2month,v2.pv as v2pv 
    from v1 join v2 on v1.id = v2.id 
    where v2.vmonth >= v1.vmonth;
    

    結果:
    在這裏插入圖片描述

  4. 求最大訪問次數和總訪問次數。
    最大訪問次數:當v2的月份是1月時,對應v1只有1條記錄,即爲33
    當v2的月份爲2月時,對應v1有2條記錄,最大訪問爲33
    當v2的月份爲3月時,對應v1有3條記錄,最大訪問爲33

    總訪問次數:v1pv的累加
    在這裏插入圖片描述
    方法2:窗口函數(sum、avg、max、min)使用方法一致

    先求出當月訪問次數

    create table v1 as 
    select id,vmonth,sum(pv) as pv from visits group by id,vmonth;
    

    結果:

    id      vmonth      pv
    A       2015-01 	33
    A       2015-02 	10
    A       2015-03 	38
    B       2015-01 	30
    B       2015-02 	15
    B       2015-03 	44
    
    select id,vmonth,pv,
    max(pv) over(partition by id order by vmonth rows between unbounded preceding and current row) as maxpv,
    sum(pv) over(partition by id order by vmonth rows between unbounded preceding and current row) as sumpv 
    from v1;
    

    解釋:

    【over】是窗口函數的關鍵字
    【partition by】按照什麼字段分區,可以理解爲分組group by
    【order by】排序,不寫order by,表示分組內所有值相加
    partition by 和 order by 配合使用 或者 distribute by 和 sort by 配合使用
    (partition by 字段 order by 字段) 後面不跟範圍條件,默認是從起點到當前行
    【rows between a and b】行的範圍條件,從a到b
    【rows between unbounded preceding and current row】第一行+當前行
    【unbounded preceding】最前面的起點(第一行)
    【current row】當前行
    【unbounded following】到後面的終點
    【3 preceding】當前行+往前數3行
    【1 following】當前行+往後數1行
    【rows between 3 preceding and 1 following】當前行+往前數3行+往後數1行

    					pv 		maxpv 	sumpv
    A       2015-01 	33      33      33
    A       2015-02 	10      33      43
    A       2015-03 	38      38      81
    B       2015-01 	30      30      30
    B       2015-02 	15      30      45
    B       2015-03 	44      44      89
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章