數據聚合和採樣

来源:https://www.cnblogs.com/StephenMeng/archive/2018/09/13/9638260.html
-Advertisement-
Play Games

基礎聚合 常見的聚合函數 count,sum,avg,max,min set hive.map.aggr=true; //mapper端預聚合,提高性能,但消耗較多記憶體 註意:只能select group by從句的欄位,否則報錯 select name, gender_age.gender, co... ...


基礎聚合 
常見的聚合函數 count,sum,avg,max,min
set hive.map.aggr=true;      //mapper端預聚合,提高性能,但消耗較多記憶體
註意:只能select group by從句的欄位,否則報錯
select name, gender_age.gender, count(*) as row_cnt  --error!
from employee
group by gender_age.gender;

如何select沒有出現在group by中的欄位?
    1)使用collect_set函數;
select gender_age.gender, collect_set(gender_age.age)[0] as random_age, count(*) as row_cnt
from employee
group by gender_age.gender;

select中使用多個聚合函數
select gender_age.gender, avg(gender_age.age) as avg_age, count(*) as row_cnt
from employee
group by gender_age.gender;

    2)使用分析函數(不需要 group by)
聚合函數和 case when 一起使用
select sum(case when gender_age.gender = "Male" then gender_age.age else 0 end) /
sum(case when gender_age.gender = "Male" then 1 else null end) as man_age_avg    -- 0 == null
from employee;

聚合函數和coalesce, if連用。 case when和if的區別?
coalesce(a1, a2, ...) - Returns the first non-null argument
求age_sum, woman_age_sum
select sum(coalesce(gender_age.age, 0)) as age_sum,
sum(if(gender_age.gender = "Female", gender_age.age, 0)) as woman_age_sum
from employee;

聚合函數不允許嵌套 如:avg(count(*)) error!

聚合函數中使用distinct 
select count(distinct gender_age.gender) as sex_uni_cnt,
count(distinct name) as name_uni_cnt
from employee;
註意:count和distinct一起使用時,只會使用一個reducer,降低性能,解決方法:
select count(*) as sex_uni_cnt
from (
select distinct gender_age.gender from employee
) a;
註意:聚合時若遇到含有null值的列,則忽略該行,如:
--創建含有null行的表
create table t as select * from (
select employee_id - 99 as val1,
employee_id - 98 as val2 from employee_hr
where employee_id <= 101
union all
select null as val1, 2 as val2 from employee_hr
where employee_id = 100
) a;
+---------+---------+--+
| t.val1  | t.val2  |
+---------+---------+--+
| 1       | 2       |
| NULL    | 2       |
| 2       | 3       |
+---------+---------+--+
select sum(val1 + val2) from t;     --第二行會被忽略,解決方法:
select sum(coalesce(val1, 0) + val2) from t;

高級聚合
grouping sets 自定義聚合
內層的grouping sets定義了每個union all中的group by要實現的數據。
select name, work_place[0] as main_place, count(employee_id) as emp_id_cnt
from employee_id
group by name, work_place[0] grouping sets((name, work_place[0]));
<==>
select name, work_place[0] as main_place, count(employee_id) as emp_id_cnt
from employee_id
group by name, work_place[0];

外層的grouping sets定義了union all要實現的數據。
select name, work_place[0] as main_place, count(employee_id) as emp_id_cnt
from employee_id
group by name, work_place[0] grouping sets((name), (work_place[0]));
<==>
select name, null as main_place, count(employee_id) as emp_id_cnt
from employee_id
group by name
union all
select null as name, work_place[0] as main_place, count(employee_id) as employee_id_cnt
from employee_id
group by work_place[0];

內外層grouping by混合使用
select name, work_place[0] as main_place, count(employee_id) as employee_id_cnt
from employee_id
group by name, work_place[0] grouping sets((name, work_place[0]), name, work_place[0], ());

煮魚:grouping sets的內容為表或記錄的別名所指向的列時,可能會出現問題,已修複。如:
select gender_age.gender, gender_age.age,
count(name) as name_uni_cnt
from employee
group by gender_age.gender, gender_age.age grouping sets((gender_age.gender, gender_age.age));

rollup and cube

rollup 創建n + 1級聚合,n為group by中的分組列
group by a, b, c with rollup <==> grouping set((a, b, c), (a, b), (a), ())
cube  創建2^n級聚合
group by a, b, c with cube 

grouping_id 表示行的列是否聚合的位向量的10進位形式??????????
select grouping_id, bin(cast(grouping_id as bigint)) as bit_vector,
name, start_date, count(employee_id) emp_id_cont
from employee_hr
group by start_date, name
with cube 
order by start_date;

having - 對group by的結果進行過濾,避免分組以後再使用子查詢
將員工按年齡分組,統計:人數<=1的年齡組
select gender_age.age 
from employee_id
group by gender_age.age having count(*) <= 1;
<==>
select a.age  
from (
select gender_age.age as age, count(*) as cnt    --內查詢中的列一定要給個別名
from employee_id
group by gender_age.age
) a
where a.cnt <= 1;  --where中不支持UDAF函數,要起個別名

分析函數
分析函數與聚合函數的區別?
聚合函數會分組,然後為每個組生成一個結果;分析函數不對結果集分組
Function(arg1,..., argn) OVER ([PARTITION BY <...>] [ORDER BY <....>] [<window_clause>])
或者 P184
function(arg1,..., argn) over w as w_n
...
window
w as ([PARTITION BY <...>] [ORDER BY <....>] [<window_clause>])

Function(arg1,..., argn):
    標準的聚合函數
    分析函數:不能在視窗從句中使用,還有lead,lag。
        ntile:將排序好的數據集分桶,並且給每行分配一個合適的桶號,適用於將數據等分

        rank:組內元素進行編號
        dense_rank:組內元素進行編號,併排的下一個元素步進1
        row_number:安照排序和分區給元素編號,每組從1開始
        percent_rank:??

        cume_dist:??計算 <= 給定值的行數, 給定值 = 總行數 / 當前行            
    視窗函數:
        lead(value_expr,[offset],[default]):視窗(組)內指定列的行向下前進offset行
        lag(value_expr,[offset],[default]):視窗(組)內指定列的行向上滯後offset行
        first_value:
        last_value:
over + :
    標準的聚合函數
    註意order by只支持一個排序鍵,變通方法:使用rows unbounded preceding視窗從句
    partition by + :基本類型的一個或多個分區列 why?
    partition by + sorted by:任意類型的一個或多個分區列/排序列
    視窗從句:視窗和組的區別?視窗是分區內的某個範圍
        作用:細顆粒度
        類型:
          ⚠️:升序時,star_expr必須小於end_expr,否則整列值為null或報異常
          行類型視窗    ROWS BETWEEN <start_expr> AND <end_expr> 當前行之前或之後的行數
          範圍類型視窗     RANGE BETWEEN <start_expr> AND <end_expr>
              兩視窗的不同點:range僅支持一個排序列,且此列只能為數字或日期。視窗的範圍由排序列決定

        若定義了order by,缺失視窗從句。預設為:range between unbounded preceding and current row 視窗為當前分區的起點到當前行
        都缺失。預設為:rows between unbounded preceding and unbounded following 視窗為當前分區

create table if not exists employee_contract (
name string,
dept_num int,
employee_id int,
salary int,
type string,
start_date date
)
row format delimited
fields terminated by '|'
stored as textfile;
load data local inpath "/home/centos/hiveessential/ch06/employee_contract.txt"
overwrite into table employee_contract;

select name, dept_num, salary,
count(*) over (partition by dept_num) as row_cnt,  --組內求和
sum(salary) over (partition by dept_num order by dept_num) as deptTotal,   --    組內數據累加
sum(salary) over (order by dept_num) as runingTotol1,   --各組之和累加, ????
sum(salary) over (order by dept_num, name rows unbounded preceding) as runingTotol2  --看不懂
from employee_contract
order by dept_num, name;

set hive.strict.checks.large.query=false;
set hive.mapred.mode=nonstrict;

select name, dept_num, salary,
count(*) over (partition by dept_num) as row_cnt,
sum(salary) over(partition by dept_num order by dept_num) as deptTotal,  
sum(salary) over(order by dept_num) as runingTotol1,   
sum(salary) over(order by dept_num, name rows unbounded preceding) as runingTotol2
from employee_contract
order by dept_num, name;
<==>獨立的視窗從句
select name, dept_num, salary,
count(*) over row_cnt,
sum(salary) over deptTotal,  
sum(salary) over runingTotol1,   
sum(salary) over runingTotol2
from employee_contract
order by dept_num, name
window
row_cnt as (partition by dept_num),
overdeptTotal as (partition by dept_num order by dept_num),
runingTotol1 as (order by dept_num),
runingTotol2 as (order by dept_num, name rows unbounded preceding);

//範圍查詢
select name, dept_num, salary, start_year,
max(salary) over (partition by dept_num order by start_year 
range between 2 preceding and current row) as win1
from (
select name, dept_num, salary, year(start_date) as start_year
from employee_contract
) a;

抽樣
1. 隨機取樣??
select name from employee_id
distribute by rand() sort by rand()
limit 5;
2. 分桶表抽樣
SELECT * FROM <BucketTable_Name> 
TABLESAMPLE(BUCKET <specified bucket number to sample> OUT OF <total number of buckets> ON [colname|RAND()]) table_alias;
select name from employee_id_buckets
tablesample(bucket 1 out of 2 on rand()) a;
3. 塊抽樣
SELECT * FROM <Table_Name> 
TABLESAMPLE(N PERCENT|ByteLengthLiteral|N ROWS) s;
按百分比大小抽樣
select name from employee_id_buckets
tablesample (20 percent) a;
按行數抽樣
select name from employee_id
tablesample (5 rows) a;
按位元組大小抽樣
select name from employee_id
tablesample (700B) a;

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一. 掛載存儲媒體 linux文件系統將所有的磁碟都併入一個虛擬目錄下,當使用新的存儲媒體之前,需要把它放到虛擬目錄下,這項工作稱為掛載(mounting) 1.1 mount 命令 在linux上用來掛載媒體的命令叫做mount. 預設情況下,mount命令會輸出當前系統上的掛載的設備列表。 1. ...
  • 系統 [root@Gao conf.d]# uname -a 工具 1、Final Shell 2、工具截圖 需要下載的部分 node.js npm cnpm vue-cli 安裝node.js 1、下載對應的版本 2、上傳到伺服器 3、解壓 # tar -xvf 4、重命名 # mv 5、進入bi ...
  • 實驗環境:Centos7虛擬機 首先創建一個普通用戶 。 [root@localhost ~] useradd gubeiqing [root@localhost ~] passwd gubeiqing Changing password for user gubeiqing. New passwo ...
  • Windows文件共用使用了SMB協議(又稱CIFS協議),該協議主要提供了文件共用和列印共用功能,分別使用TCP 139和445埠。UNIX、Linux系統提供了該協議的開源實現samba。為了方便開發和調試,在Windows宿主機和CentOS虛擬機之間通過SMB協議共用文件夾,在Window ...
  • 一、執行命令 二、根據提示輸入基本信息 三、生成的證書申請文件和私鑰文件(.key文件千萬別丟非常重要!!!美文) 四、複製csr內容粘貼到name.com的申請框中(註意包括BEGIN和END兩行) ...
  • yum install java-1.8.0-openjdk* -y ...
  • 對於每一個 Linux 學習者來說,瞭解 Linux 的文件系統結構是十分有必要的,因為在 Linux 的學習中一直流傳著這樣一句話:一切皆文件,可以說只有深入瞭解了 Linux 的文件系統,才會對 Linux 有更深刻的理解 ...
  • 一 挑戰 設計從來就是個挑戰。 當我們第一次接觸資料庫,學習資料庫基礎理論時,都需要學習範式,老師也一再強調範式是設計的基礎。範式是這門課程中的重要部分,在期末考試中也一定是個重要考點。如果我們當年大學掛科了,說不定就是範式這道題沒有做好。畢業後,當我們面試時,往往也有關於表設計方面拷問。 很多時候 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...