hive(II)--sql考查的高頻問題

  在了解別人hive能力水平的時候,不管是別人問我還是我了解別人,有一些都是必然會問的東西。問的問題也大都大同小異。這里總結一下我遇到的那些hive方面面試可能涉及的問題

  1、行轉列(列轉行)

    當我們建設數據倉庫時,我們對來自OLAP的數據進行加工以便處理成維度模型。在維度模型設計的時候就需要面對這樣的問題(其他時候可能也會用到)

    數據準備

      建表:create table shj_cnblogs(customer_id string,trans_year string,trans_amount int,product_name string) row format delimited fields terminated by ',';

      導入數據:load data local inpath '/home/www/su*****n/sample/data.csv'? into table shj_cnblogs;

          

    行轉列

      上表是一個虛擬數據(業務含義:customer_id代表一個客戶,其每年購買的產品和金額),希望將展示客戶不同年份購買了多少以及產品。呈現的數據希望是這樣的。

      

      這里我們的難點就是如何在行聚合時將產品行轉列了,這就說到hive中的函數UDTF(表生成函數)。UDTF函數有:array/explode/collect_set/collect_list等。這里使用了collect_set,腳本為:

select customer_id,trans_year,sum(trans_amount) as total_fund,concat_ws(',',collect_set(product_name)) as all_product  from  shj_cnblogs group by customer_id,trans_year;
--(當遇到不懂得函數可以用命令查看解釋:show function [extended] fun_name;)

?      上面我們將多行轉為一列,也可以轉為多列。轉多列使用的是collect_set的集合屬性,通過調用集合元素實現多行轉多列。

    列轉行

      ?假如我們虛擬了這樣的數據來描述電影的表,想要將它的列拆分多行,該怎么辦呢?

      

      這里我們使用explode函數,該函數輸入的是一個數組,后將數組中的每個元素都作為一行來輸出。但有一個明顯的限制,不能與其他列共同使用。如果要包含其他列,則需要laterval view來實現。使用lateral view需要指定視圖別名和生成的字段別人。

select film_id,actor_id,dd from shj_1 lateral view explode(split(feature_desc,',')) cc as dd ;[這里cc是視圖別名,dd是字段別名]

    假如這里需要列分割的不止一列,則使用兩次lateral view來實現。比如說這里的actor_id列是多值分布的,則寫法如下

select film_id,bb,dd from shj_1 lateral view explode(split(actor_id,',')) aa as bb lateral view explode(split(feature_desc,',')) cc as dd ;

    執行后結果如圖

    

?

?  2、窗口函數

    在做OLAP分析或報表時,常常使用窗口函數能大幅度提升我們的分析效率。在說窗口函數前,請一定要記住:在SQL處理中,窗口函數都是最后一步執行,而且僅位于Order by字句之前.

    窗口函數的關鍵字:over(),它幫助我們在行記錄上實現聚合,我們既可以看到明細數據也可以看到聚合數據(使用中,發現窗口函數可以和聚合函數一起使用的,但注意!窗口函數是僅早于order by步驟。寫sql時應注意兩者之間是否存在沖突,這點容易出錯。)。這里我們從一個樣本數據出發(客戶買東西場景),探索窗口函數的妙用(數據和內容參考博客:http://blog.csdn.net/qq_26937525/article/details/54925827,這篇博客寫的真不錯!)

jack,2015-01-01,10
tony,2015-01-02,15
jack,2015-02-03,23
tony,2015-01-04,29
jack,2015-01-05,46
jack,2015-04-06,42
tony,2015-01-07,50
jack,2015-01-08,55
mart,2015-04-08,62
mart,2015-04-09,68
neil,2015-05-10,12
mart,2015-04-11,75
neil,2015-06-12,80
mart,2015-04-13,94

    I、認識窗口函數

    我們先看看下面的三個sql語句的差異。第一個是傳統的group by聚合函數,實現以name維度的聚合,展示客戶的購買次數;第二個使用窗口函數,展示明細數據并聚合所有的購買次數(這里沒有指定分區,則針對全表);第三個先分組,對分組數據進行聚合,得出聚合的分組數。該sql可以也可寫成select distinct name,count(*) over() from shj_2;

腳本1> select name,count(*) from shj_2 group by name order by name;
jack    5
mart    4
neil    2
tony    3
腳本2> select name,count(*) over() from shj_2 order by name;
jack    14
....
jack    14
mart    14
...
tony    14
腳本3> select name,count(*) over() from shj_2 group by name order by name;
jack    4
mart    4
neil    4
tony    4

?    II、partition by下的序列函數

    上面我們說的都是全表的情況,這里我們討論一下分區的使用。在傳統sql中,我們對數據進行除重清洗時會使用到row_number() over(partition by ...order by ...)語句,這其實就是一個窗口函數的應用案例。像row_number()這樣的序列函數還有rank() over(partition by ...order by );dense_rank() over(partiton by ... order by ...)【rank:有空位;dense_rank:沒有空位】;ntile() over(partition by ... order by ...);這些函數的工作機制:先分區(partition by關鍵字后的字段),再排序(order by后的字段),然后在分區中進行序列賦值(row_number從1開始賦值,ntile是根據指定字段進行切片,不均勻時增加前面的分組數)

    示例:月度的消費排名

select name,orderdate,cost,rank() over(partition by month(orderdate) order by cost desc ) as rank_desc from shj_2;

    

??    III、聚合函數+over

    前面提到的partition by可以將數據表以指定的分式進行分區,類似于row_number()等函數,我們也可以使用聚合函數(類似有sum/count/avg/),在使用聚合函數時,指定order by與否將影響整個聚合的效果。不指定時,聚合整個分區,指定order by時,則是以order by順序累加聚合。說明:窗口函數之間是互不影響的。

--查看客戶月度消費和增加,col1是隨著時間增加的累加金額,col2是總金額
select name,orderdate,cost,sum(cost) over(partition by name order by orderdate) as col1,sum(cost) over(partition by name) as col2 
from shj_2 order by name, orderdate;

?    

    然而,分區函數的粒度還可以更加的細分,這里我們說到window子句,指定聚合的作用范圍(分區中的范圍)。這里我們需要order by來進行排序,否則無序的數據是毫無意義的。指定范圍的關鍵字有:

    PRECEDING:前面行

    FOLLOWING:后面行

    CURRENT ROW:當前行

    UMBOUNDED:起點,UNBOUNDED PRECEDING 表示從前面的起點, UNBOUNDED FOLLOWING:表示到后面的終點

?    這里我使用博客中的腳本和結果

select name,orderdate,cost,
sum(cost) over() as sample1,--所有行相加
sum(cost) over(partition by name) as sample2,--按name分組,組內數據相加
sum(cost) over(partition by name order by orderdate) as sample3,--按name分組,組內數據累加
sum(cost) over(partition by name order by orderdate rows between UNBOUNDED PRECEDING and current row )  as sample4 ,--和sample3一樣,由起點到當前行的聚合
sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING   and current row) as sample5, --當前行和前面一行做聚合
sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING   AND 1 FOLLOWING  ) as sample6,--當前行和前邊一行及后面一行
sum(cost) over(partition by name order by orderdate rows between current row and UNBOUNDED FOLLOWING ) as sample7 --當前行及后面所有行
from shj_2;

    

?    IV、常用的窗口函數

    lag(var,n[defualt_value]):向后取上第n個數據(lag:有落后的意思)

    lead(var,n[defualt_value]):向前取下第n個數據(lead:有領先的意思)

?    first_value(var):取分組內排序后,截止到當前行,第一個值

?    last_value(var):取分組內排序后,截止到當前行,最后一個值

select name,orderdate,cost,
lag(cost,1) over(partition by name order by orderdate) as first_lag_cost,    --上一次消費金額
lag(cost,2) over(partition by name order by orderdate) as second_lag_cost,   --上上一次消費金額
lead(cost,1) over(partition by name order by orderdate) as first_next_cost,  --下一次消費金額
lead(cost,2) over(partition by name order by orderdate) as first_next_cost,  --下下一次消費金額
first_value(orderdate) over(partition by name order by orderdate) as month_first_buy,  --客戶首次購買的時間
last_value(orderdate)  over(partition by name order by orderdate) as month_last_buy  --分組后截止當前行客戶最后購買時間
from shj_2;

?

?  3、數據傾斜

    傾斜的情況接觸不多,總結一下我的理解和別人的看法。數據傾斜簡單理解就是sql耗時長或在某一個reduce上半天不出結果。我們知道,hive是基于MR任務,如果在MR階段數據分配不均衡,就會導致傾斜。數據處理時,首先會進行map階段,對數據進行拆分并執行map函數,后根據partitioner接口,將數據分配到不同的reduce中進行最后的計算。理想情況下,數據均勻分配不會出現傾斜。但是由于partitioner本身是通過hash對key進行取模的特點存在一定問題,以及數據、腳本等原因,導致傾斜。處理數據傾斜,可以從sql、調整參數進行規避。

?    I、SQL優化

      a、Map-Join:在兩張表進行關聯時,將小表作為驅動表(左邊),執行MR時左邊的表會被寫入緩存中(小表不會出現內存溢出)提升執行效率。方式1/:查詢中添加/*+ MAPJOIN(SmallTableNmae)*/進行指定;方式2:設置系統參數自動判斷,

set hive.auto.convert.join=true;(自動開戶MAPJOIN優化);set hive.mapjoin.smalltable.filesize=10000000;(設置100M時自動啟用)

?

      b、進行不適用distinct count;可以替換成group by

      c、處理大表時,進行列裁剪(字段選擇),fiter操作(where條件限定)來減小任務文件

    2、參數設置

      a、hive.map.aggr=true;允許map端進行combiner操作(相當于reduce)

      b、hive.groupby.skewindata=true;負載均衡,在使用group by時常用;

      c、set hive.exec.parallel=true;set hive.exec.parallel.thread.number=16;允許并發,及最大并發數

      d、還有一些不怎么用,如合并小文件、設置bitmap index

    3、數據處理

      a、主要對null值進行處理,設置為字符常量加隨機數或在filter操作時限定

      b、建表時,合理設置分區以及字段類型

?

原創博客,轉載請注明出處!歡迎郵件溝通:shj8319@sina.com

轉載于:https://www.cnblogs.com/SunHuaJ/p/7678222.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/280140.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/280140.shtml
英文地址,請注明出處:http://en.pswp.cn/news/280140.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java概述

一、java平臺無關:jvm二、java健壯語言:無指針,語法上無指正,無內存申請與釋放。 三、java核心機制而: jvmjava垃圾收集機制 GC四、java運行過程:源程序(.java)——》java編譯器——…

時間間隔

計算當前時間與上次執行時間的時間間隔。 NSTimeInterval timetravel [[NSDate date]timeIntervalSinceDate:self.lastPlaySoundDate];if (timetravel<3.0) {DLog("時間太短&#xff0c;。。");}self.lastPlaySoundDate [NSDate date]; 轉載于:https://www.cnb…

.Net+MySQL組合開發(二) 數據訪問篇

一、建立數據庫、表、添加數據這里我們使用圖形化操作的SQL Manager 2005 Lite for MySQL來建立數據&#xff0c;它的操作界面非常類似OFFICE軟件&#xff0c;使用方便、很容量上手、下面開始建立數據庫及表單擊"Creat New DataBase"&#xff1a;新建DB輸入密碼&…

Git vs SVN

一、Git vs SVN Git 和 SVN 孰優孰好&#xff0c;每個人有不同的體驗。Git是分布式的&#xff0c;SVN是集中式的這是 Git 和 SVN 最大的區別。若能掌握這個概念&#xff0c;兩者區別基本搞懂大半。因為 Git 是分布式的&#xff0c;所以 Git 支持離線工作&#xff0c;在本地可以…

.net api 和java平臺對接技術總結

這兩天 一直和京東對接接口&#xff0c;我們用.net api 提供接口&#xff0c;對方用java調用&#xff0c;本來沒什么問題&#xff0c;但是對方對數據安全要求特別嚴&#xff0c;要驗簽&#xff0c;于是噩夢開始了。 1、在傳輸的時候&#xff0c;約定傳輸格式&#xff1a; HttpW…

Burpsuite學習(4)

2019獨角獸企業重金招聘Python工程師標準>>> burpsuite spider模塊通過跟蹤 HTML 和 JavaScript 以及提交的表單中的超鏈接來映射目標應用程序&#xff0c;它還使用了一些其他的線索&#xff0c;如目錄列表&#xff0c;資源類型的注釋&#xff0c;以及 robots.txt 文…

Git刪除分支/恢復分支

這是https://www.cnblogs.com/utank/p/7880441.html的方法&#xff0c;雖然很老現在有點不一樣&#xff0c;但總體還是能用的。 總結就是兩種方法 1.用commit的id恢復 2.用reflog的頭指針恢復 ?刪除一個已被終止的分支 如果需要刪除的分支不是當前正在打開的分支&#xff0c;使…

NetCore2.0Web應用之Startup

為什么80%的碼農都做不了架構師&#xff1f;>>> 作為main函數的程序啟動文件UseStartup 默認就是調用我們的整個應用程序的啟動文件 class Program{static void Main(string[] args){var host new WebHostBuilder().UseKestrel() // 指定WebServer為Kes…

windows XP系統下oracle完整卸載過程

NT環境下&#xff1a; 1、以NT的Administrator 登陸 2、通過控制面版-〉服務&#xff0c;停掉所有ORACLE服務 3、打開注冊表&#xff08;REGEDIT命令&#xff09;&#xff0c;刪除HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE 4、打開注冊表中的 HKEY_LOCAL_MACHINE\SYSTEM\CurrentCont…

Hadoop----hdfs的基本操作

2019獨角獸企業重金招聘Python工程師標準>>> HDFS操作文件的基本命令 1.創建文件夾 $>hdfs dfs -mkdir /user/centos/hadoop 2.展示目錄 $>hdfs dfs -ls -r /user/centos/hadoop 3.遞歸展示 $>hdfs dfs -lsr /user/centos/hadoop 4.上傳文件 $&g…

原生sql實現restful接口調用

index.php <?phpinclude ./Request.php; include ./Response.php; //獲取數據 $dataRequest::getRequest(); $resultResponse::sendResponse($data); echo $result; ?> Request.php <?php class Request{private static $method_typearray(get,post,put,delete,pa…

彈幕效果

<!DOCTYPE html><html> <head> <meta charset"UTF-8"> <title>彈幕效果</title> <script src"../../jquery-1.12.4.min.js" type"text/javascript" charset"utf-8"></script> </h…

基于.NetCore開發博客項目 StarBlog - (21) 開始開發RESTFul接口

1前言最近電腦壞了&#xff0c;開源項目的進度也受到一些影響這篇醞釀很久了&#xff0c;作為本系列第二部分&#xff08;API接口開發&#xff09;的第一篇&#xff0c;得想一個好的開頭&#xff0c;想著想著就鴿了好久&#xff0c;索性不扯那么多了&#xff0c;直接開寫吧~2關…

03 Oracle分區表

Oracle分區表 先說句題外話… 歡迎成都天府軟件園的小伙伴來面基交流經驗~ 一&#xff1a;什么是分區&#xff08;Partition&#xff09;&#xff1f; 分區是將一個表或索引物理地分解為多個更小、更可管理的部分。 分區對應用透明&#xff0c;即對訪問數據庫的應用而言&…

windows獲取本地時間_如何在Windows 8中重新獲得本地登錄

windows獲取本地時間By default a fresh Windows 8 installation prompts you to create a synchronized cloud-enabled login. While there are distinct perks to Microsoft’s live login system, sometimes you just want to keep things simple and local. Read on as we …

如何解決高并發,秒殺問題

相信不少人會被這個問題困擾&#xff0c;分享大家一篇這樣的文章&#xff0c;希望能夠幫到你&#xff01; 一、秒殺業務為什么難做&#xff1f;1&#xff09;im系統&#xff0c;例如qq或者微博&#xff0c;每個人都讀自己的數據&#xff08;好友列表、群列表、個人信息&#xf…

Spring原理之代理與動態代理模式總結(四)

2019獨角獸企業重金招聘Python工程師標準>>> 代理模式 1&#xff0c;什么是代理模式&#xff1f; 代理模式的作用是&#xff1a;為其他對象提供一種代理以控制對這個對象的訪問。2&#xff0c;代理模式有什么好處&#xff1f; 在某些情況下&#xff0c;一個客戶不…

可執行文件添加快捷方式_如何停止Windows向快捷方式文件名添加“-快捷方式”...

可執行文件添加快捷方式When you make a new shortcut in Windows, it automatically adds “- Shortcut” to the end of the shortcut’s file name. This doesn’t seem like a big deal, but they can be bothersome. Sure, you can remove the text yourself when you cre…

Red hat6.4重新安裝yum

今天在Red Hat上安裝軟件時&#xff0c;發現需要依賴軟件&#xff0c;然而在用yum指令時&#xff0c;出現了下面的錯誤&#xff1a; This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register. 出現這個問題的原因是&…

使用 BenchmarkDotNet 比較指定容量的 List 的性能

我們之前提到 List 是 .NET 中常用的數據結構&#xff0c;其在存儲大量數據時&#xff0c;如果能夠指定它的初始化容量&#xff0c;就會有性能提升。這個優化的方法并不是很明顯&#xff0c;因此本文將使用 BenchmarkDotNet 庫&#xff0c;通過定量對比的方式來證明這一點。實驗…