数据仓库-Hive
1.數(shù)據(jù)倉庫的基本概念
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-v0OhlHVi-1616598779764)(…/TypoarWrokPath/images/1615604642904.png)]
數(shù)據(jù)倉庫的特性
數(shù)據(jù)倉庫是面向主題的(Subject-Oriented )、集成的(Integrated)、非易失的(Non-Volatile)和時(shí)變的(Time-Variant )數(shù)據(jù)集合,用以支持管理決策。
1.2.1. 面向主題
數(shù)據(jù)倉庫是面向主題的,數(shù)據(jù)倉庫通過一個(gè)個(gè)主題域?qū)⒍鄠€(gè)業(yè)務(wù)系統(tǒng)的數(shù)據(jù)加載到一起,為了各個(gè)主題(如:用戶、訂單、商品等)進(jìn)行分析而建,操作型數(shù)據(jù)庫是為了支撐各種業(yè)務(wù)而建立。
1.2.2. 集成性
數(shù)據(jù)倉庫會(huì)將不同源數(shù)據(jù)庫中的數(shù)據(jù)匯總到一起,數(shù)據(jù)倉庫中的綜合數(shù)據(jù)不能從原有的數(shù)據(jù)庫系統(tǒng)直接得到。因此在數(shù)據(jù)進(jìn)入數(shù)據(jù)倉庫之前,必然要經(jīng)過統(tǒng)一與整合,這一步是數(shù)據(jù)倉庫建設(shè)中最關(guān)鍵、最復(fù)雜的一步(ETL),要統(tǒng)一源數(shù)據(jù)中所有矛盾之處,如字段的同名異義、異名同義、單位不統(tǒng)一、字長(zhǎng)不一致,等等。
1.2.3. 非易失性
操作型數(shù)據(jù)庫主要服務(wù)于日常的業(yè)務(wù)操作,使得數(shù)據(jù)庫需要不斷地對(duì)數(shù)據(jù)實(shí)時(shí)更新,以便迅速獲得當(dāng)前最新數(shù)據(jù),不至于影響正常的業(yè)務(wù)運(yùn)作。在數(shù)據(jù)倉庫中只要保存過去的業(yè)務(wù)數(shù)據(jù),不需要每一筆業(yè)務(wù)都實(shí)時(shí)更新數(shù)據(jù)倉庫,而是根據(jù)商業(yè)需要每隔一段時(shí)間把一批較新的數(shù)據(jù)導(dǎo)入數(shù)據(jù)倉庫。 數(shù)據(jù)倉庫的數(shù)據(jù)反映的是一段相當(dāng)長(zhǎng)的時(shí)間內(nèi)歷史數(shù)據(jù)的內(nèi)容,是不同時(shí)點(diǎn)的數(shù)據(jù)庫的集合,以及基于這些快照進(jìn)行統(tǒng)計(jì)、綜合和重組的導(dǎo)出數(shù)據(jù)。數(shù)據(jù)倉庫中的數(shù)據(jù)一般僅執(zhí)行查詢操作,很少會(huì)有刪除和更新。但是需定期加載和刷新數(shù)據(jù)。
1.2.4. 時(shí)變性
數(shù)據(jù)倉庫包含各種粒度的歷史數(shù)據(jù)。數(shù)據(jù)倉庫中的數(shù)據(jù)可能與某個(gè)特定日期、星期、月份、季度或者年份有關(guān)。數(shù)據(jù)倉庫的目的是通過分析企業(yè)過去一段時(shí)間業(yè)務(wù)的經(jīng)營狀況,挖掘其中隱藏的模式。雖然數(shù)據(jù)倉庫的用戶不能修改數(shù)據(jù),但并不是說數(shù)據(jù)倉庫的數(shù)據(jù)是永遠(yuǎn)不變的。分析的結(jié)果只能反映過去的情況,當(dāng)業(yè)務(wù)變化后,挖掘出的模式會(huì)失去時(shí)效性。因此數(shù)據(jù)倉庫的數(shù)據(jù)需要定時(shí)更新,以適應(yīng)決策的需要。
2數(shù)據(jù)庫與數(shù)據(jù)倉庫的區(qū)別
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-lmCOsEPg-1616598779768)(…/TypoarWrokPath/images/1615605202339.png)]
3. 數(shù)倉的分層架構(gòu)
數(shù)據(jù)倉庫的數(shù)據(jù)來源于不同的源數(shù)據(jù),并提供多樣的數(shù)據(jù)應(yīng)用,數(shù)據(jù)自下而上流入數(shù)據(jù)倉庫后向上層開放應(yīng)用,而數(shù)據(jù)倉庫只是中間集成化數(shù)據(jù)管理的一個(gè)平臺(tái)。
源數(shù)據(jù)層(ODS)`:
? 此層數(shù)據(jù)無任何更改,直接沿用外圍系統(tǒng)數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù),不對(duì)外開放;為臨時(shí)存儲(chǔ)層,是接口數(shù)據(jù)的臨時(shí)存儲(chǔ)區(qū)域,為后一步的數(shù)據(jù)處理做準(zhǔn)備。
數(shù)據(jù)倉庫層(DW)`:
? 也稱為細(xì)節(jié)層,DW層的數(shù)據(jù)應(yīng)該是一致的、準(zhǔn)確的、干凈的數(shù)據(jù),即對(duì)源系統(tǒng)數(shù)據(jù)進(jìn)行了清洗(去除了雜質(zhì))后的數(shù)據(jù)。
數(shù)據(jù)應(yīng)用層(DA或APP)`:
? 前端應(yīng)用直接讀取的數(shù)據(jù)源;根據(jù)報(bào)表、專題分析需求而計(jì)算生成的數(shù)據(jù)。
數(shù)據(jù)倉庫從各數(shù)據(jù)源獲取數(shù)據(jù)及在數(shù)據(jù)倉庫內(nèi)的數(shù)據(jù)轉(zhuǎn)換和流動(dòng)都可以認(rèn)為是ETL(抽取Extra, 轉(zhuǎn)化Transfer, 裝載Load)的過程,ETL是數(shù)據(jù)倉庫的流水線,也可以認(rèn)為是數(shù)據(jù)倉庫的血液,它維系著數(shù)據(jù)倉庫中數(shù)據(jù)的新陳代謝,而數(shù)據(jù)倉庫日常的管理和維護(hù)工作的大部分精力就是保持ETL的正常和穩(wěn)定。
為什么要對(duì)數(shù)據(jù)倉庫分層?
用空間換時(shí)間,通過大量的預(yù)處理來提升應(yīng)用系統(tǒng)的用戶體驗(yàn)(效率),因此數(shù)據(jù)倉庫會(huì)存在大量冗余的數(shù)據(jù);不分層的話,如果源業(yè)務(wù)系統(tǒng)的業(yè)務(wù)規(guī)則發(fā)生變化將會(huì)影響整個(gè)數(shù)據(jù)清洗過程,工作量巨大。
通過數(shù)據(jù)分層管理可以簡(jiǎn)化數(shù)據(jù)清洗的過程,因?yàn)榘言瓉硪徊降墓ぷ鞣值搅硕鄠€(gè)步驟去完成,相當(dāng)于把一個(gè)復(fù)雜的工作拆成了多個(gè)簡(jiǎn)單的工作,把一個(gè)大的黑盒變成了一個(gè)白盒,每一層的處理邏輯都相對(duì)簡(jiǎn)單和容易理解,這樣我們比較容易保證每一個(gè)步驟的正確性,當(dāng)數(shù)據(jù)發(fā)生錯(cuò)誤的時(shí)候,往往我們只需要局部調(diào)整某個(gè)步驟即可。
數(shù)倉的元數(shù)據(jù)管理
元數(shù)據(jù)(Meta Date),主要記錄數(shù)據(jù)倉庫中模型的定義、各層級(jí)間的映射關(guān)系、監(jiān)控?cái)?shù)據(jù)倉庫的數(shù)據(jù)狀態(tài)及ETL的任務(wù)運(yùn)行狀態(tài)。一般會(huì)通過元數(shù)據(jù)資料庫(Metadata Repository)來統(tǒng)一地存儲(chǔ)和管理元數(shù)據(jù),其主要目的是使數(shù)據(jù)倉庫的設(shè)計(jì)、部署、操作和管理能達(dá)成協(xié)同和一致。
元數(shù)據(jù)是數(shù)據(jù)倉庫管理系統(tǒng)的重要組成部分,元數(shù)據(jù)管理是企業(yè)級(jí)數(shù)據(jù)倉庫中的關(guān)鍵組件,貫穿數(shù)據(jù)倉庫構(gòu)建的整個(gè)過程,直接影響著數(shù)據(jù)倉庫的構(gòu)建、使用和維護(hù)。
構(gòu)建數(shù)據(jù)倉庫的主要步驟之一是ETL。這時(shí)元數(shù)據(jù)將發(fā)揮重要的作用,它定義了源數(shù)據(jù)系統(tǒng)到數(shù)據(jù)倉庫的映射、數(shù)據(jù)轉(zhuǎn)換的規(guī)則、數(shù)據(jù)倉庫的邏輯結(jié)構(gòu)、數(shù)據(jù)更新的規(guī)則、數(shù)據(jù)導(dǎo)入歷史記錄以及裝載周期等相關(guān)內(nèi)容。數(shù)據(jù)抽取和轉(zhuǎn)換的專家以及數(shù)據(jù)倉庫管理員正是通過元數(shù)據(jù)高效地構(gòu)建數(shù)據(jù)倉庫。
- 用戶在使用數(shù)據(jù)倉庫時(shí),通過元數(shù)據(jù)訪問數(shù)據(jù),明確數(shù)據(jù)項(xiàng)的含義以及定制報(bào)表。
- 數(shù)據(jù)倉庫的規(guī)模及其復(fù)雜性離不開正確的元數(shù)據(jù)管理,包括增加或移除外部數(shù)據(jù)源,改變數(shù)據(jù)清洗方法,控制出錯(cuò)的查詢以及安排備份等。
元數(shù)據(jù)可分為技術(shù)元數(shù)據(jù)和業(yè)務(wù)元數(shù)據(jù)。技術(shù)元數(shù)據(jù)為開發(fā)和管理數(shù)據(jù)倉庫的IT 人員使用,它描述了與數(shù)據(jù)倉庫開發(fā)、管理和維護(hù)相關(guān)的數(shù)據(jù),包括數(shù)據(jù)源信息、數(shù)據(jù)轉(zhuǎn)換描述、數(shù)據(jù)倉庫模型、數(shù)據(jù)清洗與更新規(guī)則、數(shù)據(jù)映射和訪問權(quán)限等。而業(yè)務(wù)元數(shù)據(jù)為管理層和業(yè)務(wù)分析人員服務(wù),從業(yè)務(wù)角度描述數(shù)據(jù),包括商務(wù)術(shù)語、數(shù)據(jù)倉庫中有什么數(shù)據(jù)、數(shù)據(jù)的位置和數(shù)據(jù)的可用性等,幫助業(yè)務(wù)人員更好地理解數(shù)據(jù)倉庫中哪些數(shù)據(jù)是可用的以及如何使用。
由上可見,元數(shù)據(jù)不僅定義了數(shù)據(jù)倉庫中數(shù)據(jù)的模式、來源、抽取和轉(zhuǎn)換規(guī)則等,而且是整個(gè)數(shù)據(jù)倉庫系統(tǒng)運(yùn)行的基礎(chǔ),元數(shù)據(jù)把數(shù)據(jù)倉庫系統(tǒng)中各個(gè)松散的組件聯(lián)系起來,組成了一個(gè)有機(jī)的整體。
Hive的基本概念
什么是 Hive
Hive是基于Hadoop的一個(gè)數(shù)據(jù)倉庫工具,可以將****結(jié)構(gòu)化的數(shù)據(jù)****文件映射為一張數(shù)據(jù)庫表,并提供類SQL查詢功能。其本質(zhì)是將SQL轉(zhuǎn)換為MapReduce的任務(wù)進(jìn)行運(yùn)算,底層由HDFS來提供數(shù)據(jù)的存儲(chǔ),說白了hive可以理解為一個(gè)將SQL轉(zhuǎn)換為MapReduce的任務(wù)的工具,甚至更進(jìn)一步可以說hive就是一個(gè)MapReduce的客戶端
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-tvSdHLGv-1616598779771)(…/TypoarWrokPath/images/1615646634160.png)]
為什么使用 Hive
1.采用類SQL語法去操作數(shù)據(jù),提供快速開發(fā)的能力。
2.避免了去寫MapReduce,減少開發(fā)人員的學(xué)習(xí)成本。
3.功能擴(kuò)展很方便。
Hive的架構(gòu)
用戶接口
包括CLI、JDBC/ODBC、WebGUI。其中,CLI(command line interface)為shell命令行;JDBC/ODBC是Hive的JAVA實(shí)現(xiàn),與傳統(tǒng)數(shù)據(jù)庫JDBC類似;WebGUI是通過瀏覽器訪問Hive。
元數(shù)據(jù)存儲(chǔ)
通常是存儲(chǔ)在關(guān)系數(shù)據(jù)庫如mysql/derby中。Hive 將元數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)庫中。Hive 中的元數(shù)據(jù)包括表的名字,表的列和分區(qū)及其屬性,表的屬性(是否為外部表等),表的數(shù)據(jù)所在目錄等。
解釋器、編譯器、優(yōu)化器、執(zhí)行器:
完成HQL 查詢語句從詞法分析、語法分析、編譯、優(yōu)化以及查詢計(jì)劃的生成。生成的查詢計(jì)劃存儲(chǔ)在HDFS 中,并在隨后有MapReduce 調(diào)用執(zhí)行。
5.查看日志方法
進(jìn)入到日志的目錄里面,使用命令 tail -f hive.log
6.HIVE的sql執(zhí)行原理
是通過sql語句去解析元數(shù)據(jù),根據(jù)元數(shù)據(jù)找到HDFS的路徑,找到對(duì)應(yīng)的內(nèi)容
select * from test :在hive中的解釋;from 就會(huì)先去找元數(shù)據(jù)如果存在就會(huì)通過元數(shù)據(jù)提供的路徑到HDFS的路徑,然后把把表名拼接上去,就形成了一個(gè)完整的hdfs路徑,就可以在hdfs中找到對(duì)應(yīng)的內(nèi)容
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-H4EDchAG-1616598779773)(…/TypoarWrokPath/images/1615734204375.png)]
7.使用jdbc連接
都要在hive目錄下執(zhí)行
1.開啟metastore
bin/hive --service metastore
2.開啟hiveserver2
bin/hive --service hiveserver2
3.連接jdbc
bin/beeline -u jdbc:hive2://hadoop102:10000 -n atguigu
8.執(zhí)行報(bào)錯(cuò)bin/beeline -u jdbc:hive2://hadoop102:10000 -n atguigu
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-dNG6E87k-1616598779775)(…/TypoarWrokPath/images/1615740629757.png)]
解決方案在hadoop 的etc下面hadoop的coer.site.xml中加入如下配置
atguigu根據(jù)你自己的用戶組來定
hadoop.proxyuser.atguigu.hosts * <property><name>hadoop.proxyuser.atguigu.groups</name><value>*</value> </property>9.日志位置
cd/tmp/atguigu tail -f hive 實(shí)時(shí)監(jiān)控日志
10.查看進(jìn)程
1.查看元數(shù)據(jù)服務(wù)進(jìn)程
-v 表示不包含grep自己
ps -ef |grep -v grep |grep -i HiveMetastore
2.獲取端口號(hào)
awk 表示根據(jù)空格進(jìn)行拆分
$2 代表下標(biāo)為二的
ps -ef |grep -v grep |grep -i HiveMetastore |awk ‘{print $2}’
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-uer9VxWW-1616598779776)(…/TypoarWrokPath/images/1615743414567.png)]
11.解決中文亂碼問題
# 創(chuàng)建表(row format delimited fields terminated by '\t')插入數(shù)據(jù)格式以'\t'分隔 create table teacher(t_id string,t_name string) row format delimited fields terminated by '\t' create table course(c_id string,c_course string,t_id string) row format delimited fields terminated by '\t' create table score(s_id string,c_id string,s_score string) row format delimited fields terminated by '\t' create table student(s_id string,s_name string,s_birth date,s_sex string) row format delimited fields terminated by '\t' # 以這種方式導(dǎo)入數(shù)據(jù)不會(huì)導(dǎo)致中文亂碼 插入對(duì)應(yīng)格式數(shù)據(jù) 'hdfs://用戶名:8020/路徑+文件名' 插入完成文件會(huì)丟失 LOAD DATA INPATH 'hdfs://singlenode:8020/Hive/school/teacher.txt' INTO TABLE teacher;12.操作集合類型案列
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-XJm0UCDw-1616598779778)(…/TypoarWrokPath/images/1615833288281.png)]
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-lx30Uep0-1616598779778)(…/TypoarWrokPath/images/1615833308561.png)]
1案列操作
//(1)假設(shè)某表有如下一行,我們用 JSON 格式來表示其數(shù)據(jù)結(jié)構(gòu)。在 Hive 下訪問的格式為 {"name": "songsong","friends": ["bingbing" , "lili"] , //列表 Array, "children": { //鍵值 Map,"xiao song": 18 ,"xiaoxiao song": 19}"address": { //結(jié)構(gòu) Struct,"street": "hui long guan","city": "beijing"} } //創(chuàng)建本地測(cè)試文件 test.txt 上傳到hdsf文件系統(tǒng)中 路徑/user/hive/warehouse/mydata.db/test01 songsong,bingbing_lili,xiao song:18_xiaoxiao song:19,hui long guan_beijing yangyang,caicai_susu,xiao yang:18_xiaoxiao yang:19,chao yang_beijing //創(chuàng)建表 create table test01(name string,friends array<string>,children map<string, int>,address struct<street:string, city:string> )row format delimited fields terminated by ',' //列分隔符collection items terminated by '_' //MAP STRUCT 和 ARRAY 的分隔符(數(shù)據(jù)分割符號(hào))map keys terminated by ':' //map內(nèi)部分隔符lines terminated by '\n'; //行分隔符 //查詢array集合 ,和java一樣根據(jù)下標(biāo)查詢 select friends[0] from test01; //查詢map鍵值對(duì) select children['xiao song'] from test01;[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-z7JIetB0-1616598779779)(…/TypoarWrokPath/images/1615833636777.png)]
13.hive的外部表和內(nèi)部表
1.外部表和內(nèi)部表區(qū)別
14.數(shù)據(jù)導(dǎo)入\導(dǎo)出方式
1.使用本地文件插入表數(shù)據(jù)
load data local inpath ‘/opt/employee.txt’ into table employee; #以copy的方式導(dǎo)入數(shù)據(jù)
2.使用HDFS 的文件插入表數(shù)據(jù)
load data inpath ‘hdfs://sinlenode:8020/root/data/employee.txt’ into table emp.employee_ext; #沒有l(wèi)ocal,使用hdfs上的mv命令導(dǎo)入數(shù)據(jù)
3.使用insert插入數(shù)據(jù)
insert overwrite table student_par select id, name from student where month=‘201709’;
insert into:以追加數(shù)據(jù)的方式插入到表或分區(qū),原有數(shù)據(jù)不會(huì)刪除
insert overwrite:會(huì)覆蓋表中已存在的數(shù)據(jù)
注意:
Hive支持從同一個(gè)表進(jìn)行多次插入
INSERT INTO中TABLE關(guān)鍵字是可選的
INSERT INTO可以指定插入到哪些字段中
如:INSERT INTO t(x,y,z)
INSERT INTO table_name VALUES,支持插入值列表
數(shù)據(jù)插入必須與指定列數(shù)相同
4.多表(多分區(qū))插入模式(根據(jù)多張表查詢結(jié)果)
from student insert overwrite table student partition(month='201707') select id, name where month='201709' insert overwrite table student partition(month='201706') select id, name where month='201709';5.如果有分區(qū)的導(dǎo)入方式
-- LOCAL表示文件位于本地,OVERWRITE表示覆蓋現(xiàn)有數(shù)據(jù) LOAD DATA LOCAL INPATH '/home/dayongd/Downloads/employee.txt' OVERWRITE INTO TABLE employee_partitioned PARTITION (year=2014, month=12);6.export / import
1.將表的數(shù)據(jù)到入到hdfs 上面
export table order_items02 To '/order/export' ; --路徑必須不存在2.將導(dǎo)出的數(shù)據(jù)導(dǎo)入到表的里面
import table o_01 from '/order/export'; --表名可以不存在 o_01是表名可以不存在7.將hive數(shù)倉的數(shù)據(jù)導(dǎo)入到本地
--local 路徑用本地的路徑 overwrite表示覆蓋原來的數(shù)據(jù) from order_items02 insert overwrite local directory '/opt/data/input/' select *; --沒有l(wèi)ocal 的就上傳到hdfs中文件夾可以不存在 from order_items02 insert overwrite directory '/opt/data/input/' select *; --加了overwirte 覆蓋 from order_items02 insert overwrite table order_itemstest '/opt/data/input/' select *;把值為null 的列放到最前面
--在使用left join(任何一種join只要有空值的時(shí)候就可以)的時(shí)候?qū)⒘袨閚ull的放到最前面 order by asc升序 select * from customers cus left join orders ord on cus.customer_id=ord.customer_id order by order_id limit 30;把值為null 的列放到最后面
--在使用left join(任何一種join只要有空值的時(shí)候就可以)的時(shí)候?qū)⒘袨閚ull的放到最前面 order by desc升序 select * from customers cus left join orders ord on cus.customer_id=ord.customer_id order by order_id desc;15.刪除包含有的數(shù)據(jù)
2、 使用 cascade 關(guān)鍵字 drop database if exists 數(shù)據(jù)庫名 cascade; 可以刪除包含有表的數(shù)據(jù)庫
3.數(shù)據(jù)出錯(cuò)恢復(fù) truncate table bigdata3.student; 可以讓索引回到1,清空所有的數(shù)據(jù)
4.HIVE高建表語句
1.CTAS – as select * from test 方式建表(會(huì)復(fù)制表結(jié)構(gòu)和表數(shù)據(jù))
2. 注:CTAS不能創(chuàng)建partition, external, bucket table
3.Like (只復(fù)制表結(jié)構(gòu),不復(fù)制表數(shù)據(jù))
create table employee_like like employee;
16.union all 和 union 的區(qū)別
union和union all的區(qū)別是,union會(huì)自動(dòng)壓縮多個(gè)結(jié)果集合中的重復(fù)結(jié)果,而union all則將所有的結(jié)果全部顯示出來,不管是不是重復(fù)。
Union:(兩張表的字段必須要是一樣的)對(duì)兩個(gè)結(jié)果集進(jìn)行并集操作,不包括重復(fù)行,同時(shí)進(jìn)行默認(rèn)規(guī)則的排序;
UNION在進(jìn)行表鏈接后會(huì)篩選掉重復(fù)的記錄,所以在表鏈接后會(huì)對(duì)所產(chǎn)生的結(jié)果集進(jìn)行排序運(yùn)算,刪除重復(fù)的記錄再返回結(jié)果。
實(shí)際大部分應(yīng)用中是不會(huì)產(chǎn)生重復(fù)的記錄,最常見的是過程表與歷史表UNION
Union All:對(duì)兩個(gè)結(jié)果集進(jìn)行并集操作,包括重復(fù)行,不進(jìn)行排序;
如果返回的兩個(gè)結(jié)果集中有重復(fù)的數(shù)據(jù),那么返回的結(jié)果集就會(huì)包含重復(fù)的數(shù)據(jù)了
注意:如果數(shù)據(jù)本身不存在重復(fù)數(shù)據(jù) ,使用 union ,union all ,使用union all 的效率更高
select stu.*,c1.c_course,c1.s_score from school.student stu ,(select s_id,c_course,s_score from school.score s1,school.course cou where cou.c_id =1 and s1.c_id = cou.c_id ) c1 ,(select s_id,s_score from school.score s2 ,school.course cou where cou.c_id =2 and s2.c_id = cou.c_id) c2 where c1.s_id in (c2.s_id) and c1.s_score >c2.s_score and c1.s_id in (stu.s_id);17.使用WITH查詢
WITHc1 AS (select sco.s_id,sco.c_id,sco.s_score from school.score sco ,school.course cou where sco.c_id='01' and sco.c_id = cou.c_id),c2 AS (select sco.s_id,sco.c_id,sco.s_score from school.score sco,school.course cou where sco.c_id='02' and sco.c_id = cou.c_id)select stu.*,cc1.s_score from school.student stu,c1 cc1 ,c2 cc2 where cc1.s_id in (stu.s_id ) and cc1.s_id in (cc2.s_id) and cc1.s_score > cc2.s_score[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-JElVmCXv-1616598779781)(…/TypoarWrokPath/images/1615909392348.png)]
18.創(chuàng)建外部表 --external
1.要注意位置的順序
create external table employee(name string,work_place ARRAY<string>,sex_age STRUCT<sex:string,age:int>,skill_score MAP<string,int>,depart_title MAP<string,ARRAY<string>>)comment'這是一個(gè)員工表'row format delimited fields terminated by'|' --根據(jù)什么符號(hào)拆分collection items terminated by',' map keys terminated by ':' stored as textfile --指定文件的類型tblproperties ('skip.header.line.count'='1'); --去掉文件中頭部的N行數(shù)據(jù),這里為1行location 'hdfs://singlenode132:8020/epm/employee';--指定外部表的存放位置1.創(chuàng)建完表之后修改表不讀取第一行
alter table customer set tblproperties ('skip.header.line.count'='1'); --設(shè)定不讀取數(shù)據(jù)中頭部的N行數(shù)據(jù),這里為1行19查看表結(jié)構(gòu)
1.desc fromatted 表名
desc formatted employee;20.查詢數(shù)據(jù)庫的詳情
desc database 數(shù)據(jù)庫名
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-QksQrMJJ-1616598779782)(…/TypoarWrokPath/images/1615911476633.png)]
21.建表語法
--創(chuàng)建內(nèi)部表 create external table employee(name string,work_place ARRAY<string>,sex_age STRUCT<sex:string,age:int>,skill_score MAP<string,int>,depart_title MAP<string,ARRAY<string>>)comment'這是一個(gè)員工表'row format delimited fields terminated by'|' --根據(jù)什么符號(hào)拆分collection items terminated by',' map keys terminated by ':' stored as textfile --指定文件的類型tblproperties ('skip.header.line.count'='1'); --去掉文件中頭部的N行數(shù)據(jù),這里為1行location 'hdfs://singlenode132:8020/epm/employee';--指定外部表的存放位置--創(chuàng)建內(nèi)部表 create table employee(name string,work_place ARRAY<string>,sex_age STRUCT<sex:string,age:int>,skill_score MAP<string,int>,depart_title MAP<string,ARRAY<string>>)comment'這是一個(gè)員工表' row format delimited fields terminated by'|' --根據(jù)什么符號(hào)拆分collection items terminated by',' --集合使用什么隔開的map keys terminated by ':' --map之間的隔開符stored as textfile --指定文件的類型tblproperties ('skip.header.line.count'='1'); --去掉文件中頭部的N行數(shù)據(jù),這里為1行--使用 as select 建表create table 新表名 as select * from student;1.建完表之后修改屬性不讀取第一行
? alter table customer set tblproperties (‘skip.header.line.count’=‘1’); --設(shè)定不讀取數(shù)據(jù)中頭部的N行數(shù)據(jù),這里為1行
22.內(nèi)部表和外部表互相轉(zhuǎn)換
1.alter table 表名 set tblproperties(‘EXTERNAL’=‘TRUE’); FALSE 為內(nèi)部表 TRUE 為外部表
alter table test02 set tblproperties(‘EXTERNAL’=‘TRUE’);
23.自定義分割符
create table test03(id int,name string ) row format delimited fields terminated by ‘,’ ;
24.修改表名
1.alter table 舊表名 rename to 新表名;
alter table test03 rename to test04;
25.修改列名
alter table 表名 change column 舊列名 新列名 新的數(shù)據(jù)類型; 如果舊列名是string類型的,就不能修改,因?yàn)閟tring可以轉(zhuǎn)換為很多類型
2.alter table 表名 replace columns(deptno string, dname string, loc string); 所有的列都會(huì)被替換
1alter table dept change column deptdesc desc string;
2alter table dept replace columns(deptno string, dname string, loc string);
26.添加列名
1.alter table 表名 add columns(新增列名 類型);
alter table dept add columns(deptdesc string);
27.添加分區(qū)
分區(qū)是指分文件夾
1.靜態(tài)分區(qū)
開啟動(dòng)態(tài)分區(qū)參數(shù)設(shè)置
1.開啟動(dòng)態(tài)分區(qū)功能(默認(rèn) true,開啟)
hive.exec.dynamic.partition=true
2.設(shè)置為非嚴(yán)格模式(動(dòng)態(tài)分區(qū)的模式,默認(rèn) strict,表示必須指定至少一個(gè)分區(qū)為
nonstrict 模式表示允許所有的分區(qū)字段都可以使用動(dòng)態(tài)分區(qū)。)
hive.exec.dynamic.partition.mode=nonstrict
hadoop 新增分區(qū)功能
--創(chuàng)建一張表指定分區(qū)一個(gè)字段 create table dept_no_par2(dname string, loc string) partitioned by (deptno int) --指定分區(qū)列row format delimited fields terminated by ' ';--直接導(dǎo)入數(shù)據(jù) 指定分區(qū)列必須放到最后一列 insert into table dept_no_par2 select dname,loc,deptno from mydata.dept;--創(chuàng)建一張表指定分區(qū)段兩個(gè)字段 create table dept_no_par2(dname string, loc string) partitioned by (deptno int,hour int) --指定分區(qū)列row format delimited fields terminated by ' ';--直接導(dǎo)入數(shù)據(jù) 指定分區(qū)列必須放到最后一列 insert into table dept_no_par2 select dname,loc,deptno,hour from mydata.dept; --注意會(huì)默認(rèn)分區(qū)[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-gjtdpUDQ-1616598779784)(…/TypoarWrokPath/images/1616516350956.png)]
2.動(dòng)態(tài)分區(qū)
--不能使用 load data inpath 'hdfs://sinlenode:8020/root/data/employee.txt' into table emp.employee_ext; 去添加數(shù)據(jù) --將employee_hr的所有數(shù)據(jù)都插入到employee_partitioned的表中insert into table hive_demo.employee_partitioned partition(year,month) select name as name , num as num, phone as phone, shijian as shijian, year(shijian) as year ,month(shijian) as month from hive_demo.employee_hr;3.靜態(tài)分區(qū)和動(dòng)態(tài)分區(qū)的區(qū)別
1.靜態(tài)分區(qū)需要手動(dòng)去指定,而動(dòng)態(tài)分區(qū)是基于查詢參數(shù)的位置去推斷分區(qū)的名稱
2.靜態(tài)分區(qū)的列是通過用戶在編譯時(shí)期傳遞過來的,而動(dòng)態(tài)分區(qū)只有在sql執(zhí)行時(shí)才能確定
28.添加分桶
1.創(chuàng)建分桶
create table stu_buck(id int, name string) clustered by(id) into 4 buckets --最好設(shè)置成-1 如果進(jìn)行mr的時(shí)候只有兩個(gè)job任務(wù)的話那么他就值分了兩個(gè)桶 row format delimited fields terminated by ' ';--導(dǎo)入數(shù)據(jù) load data local inpath '/opt/module/data/stu.txt' into table stu_buck;分桶表操作需要注意的事項(xiàng)
(1)reduce 的個(gè)數(shù)設(shè)置為-1,讓 Job 自行決定需要用多少個(gè) reduce 或者將 reduce 的個(gè)
數(shù)設(shè)置為大于等于分桶表的桶數(shù)
(2)從 hdfs 中 load 數(shù)據(jù)到分桶表中,避免本地文件找不到問題
1.分桶對(duì)應(yīng)于hdfs的文件
2.更高的查詢處理
3.根據(jù)"桶列" 的哈希函數(shù)將數(shù)據(jù)進(jìn)行分桶
4.分桶只有動(dòng)態(tài)分桶 – SET hive.enforce.bucketing = true; 設(shè)置動(dòng)態(tài)分桶
5.定義分桶
CLUSTERED BY (employee_id) INTO 2 BUCKETS —分桶的列必須是要表中已有的列
分桶數(shù)最好是2的n次方
29.分桶抽樣
1.什么是分桶表
分桶是將數(shù)據(jù)集分解成更容易管理的若干部分的一個(gè)技術(shù),是比表或分區(qū)更為細(xì)粒度的數(shù)據(jù)范圍劃分。針對(duì)某一列進(jìn)行桶的組織,對(duì)列值哈希,然后除以桶的個(gè)數(shù)求余,決定將該條記錄存放到哪個(gè)桶中。
2.總結(jié)
1.隨機(jī)抽樣基于整行數(shù)據(jù)
--語法: TABLESAMPLE(BUCKET x OUT OF y) --注意:x 的值必須小于等于 y 的值,否則 --FAILED: SemanticException [Error 10061]: Numerator should not be bigger --than denominator in sample clause for table stu_buck--把數(shù)據(jù)分成32份 3表示從第三個(gè)桶往后找數(shù)據(jù) SELECT * FROM table_name TABLESAMPLE(BUCKET 3 OUT OF 32 ON rand()) s;2.隨機(jī)抽樣基于指定列(使用分桶列更高效)
SELECT * FROM table_name TABLESAMPLE(BUCKET 3 OUT OF 32 ON id) s;3.隨機(jī)抽樣基于block suze
SELECT * FROM table_name TABLESAMPLE(10 PERCENT) s; --抽取百分之十 SELECT * FROM table_name TABLESAMPLE(1M) s;--抽取一兆 SELECT * FROM table_name TABLESAMPLE(10 rows) s; --抽取十行30.正則表達(dá)式
--解釋點(diǎn) (.) 表示匹配除\n之外的其他任務(wù)字符串 --解釋加(+) 表示匹配匹配前面的子字符串一次或則多次 SELECT `^o.*` FROM offers; --^ 表示以什么開頭的 .*表示后面可以 有 或者 沒有 數(shù)據(jù) -- (.+y) 解釋 表示在這個(gè)表達(dá)式前面一定要有其他的值 select name,regexp(name,'^J.+y.+') as match from emp.employee_partition; --正則匹配name以J卡頭,包含y的行,結(jié)果是true 、 false select name ,regexp(name,'.*ill.+') as Jy1 --必須有ill連在一起 ,regexp(name,'.*[il12345678]+.+') as Jy2 --任選一個(gè)字符有出現(xiàn) ,regexp(name,'.*[i1l2345678]{3}.+') as Jy3 --任選3個(gè)字符連在一起出現(xiàn) from emp.employee_partition ;select name ,regexp(name,'^J.+y.+') as Jy , regexp(work_place[0],'^T.+ron.+') as Tron --去匹配集合 from emp.employee_partition where Jy==true ;--選出包含name字段的列名,顯示這些列的數(shù)據(jù) --注意要先執(zhí)行 SET hive.support.quoted.identifiers = none; --才能使用 select `.*name.*` from emp.employee_ext; --表示除了col_name1 col_name2 col_name3 的列其他全部查出來 select `(col_name1|col_name2| col_name3)?+.+` from table;--匹配多個(gè)列名 --方法1 SET hive.support.quoted.identifiers = none; select `(.*id.*)|(.*name.*)` from customers; --方法2 SET hive.support.quoted.identifiers = none; select `.*id.*`,`.*name.*`,`.*city.*` from customers limit 5; --方法3 select `(.*(id|name|city).*)` from customers;31.虛擬列
hive 的虛擬列 主要有以下幾個(gè)參數(shù)
INPUT__FILE__NAME --進(jìn)行劃分的輸入文件名
BLOCK__OFFSET__INSIDE__FILE --文中的塊內(nèi)偏移量
ROW__OFFSET__INSIDE__BLOCK (默認(rèn)不開啟,需設(shè)置參數(shù))–文件的行偏移量
注意 每個(gè) __ 都是 兩個(gè)下劃線~
1.INPUT__FILE__NAME --map任務(wù)讀入File的全路徑 select *, INPUT__FILE__NAME from categories; 2.BLOCK__OFFSET__INSIDE__FILE --如果是RCFile或者是SequenceFile塊壓縮格式文件則顯示Block file Offset,也就是當(dāng)前快在文件的第一個(gè)字偏移量,如果是TextFile,顯示當(dāng)前行的第一個(gè)字節(jié)在文件中的偏移量 select *, BLOCK__OFFSET__INSIDE__FILE from categories; 3.ROW__OFFSET__INSIDE__BLOCK --(默認(rèn)不開啟,需設(shè)置參數(shù)) --RCFile和SequenceFile顯示row number, --textfile顯示為0 --注:若要顯示ROW__OFFSET__INSIDE__BLOCK ,必須設(shè)置set hive.exec.rowoffset=true;set hive.exec.rowoffset=true; --設(shè)置 select *, ROW__OFFSET__INSIDE__BLOCK from categories;1.INPUT____FILE__NAME 結(jié)果
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-ReOsRzWY-1616598779786)(…/TypoarWrokPath/images/1616083346140.png)]
2.BLOCK____OFFSET_____INSIDE______FILE結(jié)果
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-CE2JAdrW-1616598779787)(…/TypoarWrokPath/images/1616083494422.png)]
3.ROW__OFFSET__INSIDE__BLOCK 結(jié)果
0表示是txt文件
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-vZKJQgUE-1616598779788)(…/TypoarWrokPath/images/1616083989074.png)]
32.視圖
1.使用視圖的注意點(diǎn)
- Hive中的試圖,僅僅是一個(gè)sql語句的快捷方式
- hive中的視圖只是邏輯視圖,沒有物化視圖
- hive的視圖,不支持增刪改,只支持查詢
- hive的視圖,只有的查詢的時(shí)候,才會(huì)真正執(zhí)行
2.創(chuàng)建視圖
create view 新建視圖名 as select * from 表名;
show views ; #只查看視圖
desc formatted|extended 視圖名 ;#查看視圖的詳細(xì)信息 formatted 查看全部信息 extended 是查看表結(jié)構(gòu)
drop view 視圖名; #刪除視圖
側(cè)視圖
1.創(chuàng)建側(cè)視圖
SELECT *,s_birth FROM student LATERAL VIEW explode(split(s_birth,'-')) a AS s; -- LATERAL VIEW explode(split(s_birth,'-')) 返回一個(gè)數(shù)組 變成列進(jìn)行輸出--outer 即使output為空也會(huì)生成結(jié)果 SELECT *,s_birthFROM student LATERAL VIEW OUTER explode(split(null,'-')) a AS s;--支持多層級(jí) select name,wps,skill,score from employee lateral view explode(work_place) work_place_single as wps lateral view explode(skills_score) sks as skill,score;[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-Gz2g59n5-1616598779790)(…/TypoarWrokPath/images/1616210901091.png)]
33.JOIN筆記
1.內(nèi)連接 inner join
--內(nèi)連接,只有進(jìn)行連接的兩個(gè)表中都存在與連接條件相匹配的數(shù)據(jù)才會(huì)被留下來 select * from score sco inner join student stu on sco.s_id=stu.s_id;[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-WVKQfle5-1616598779791)(…/TypoarWrokPath/images/1616206611766.png)]
2.左外連接 left join
--A left join B 是以A表的記錄為基礎(chǔ)的,A可以看成左表,B可以看成右表,left join是以左表為準(zhǔn)的.--意思說,左表(A)的記錄將會(huì)全部表示出來(不管右邊的表中是否存在與它們匹配的行),而右表(B)只會(huì)顯示符合搜索條件的記錄,比如符合on,where中的條件。B表記錄不足的地方均為NULL. A left join B 等價(jià)B right join A --(在數(shù)據(jù)庫中成績(jī)只有七個(gè)人,但是學(xué)生有八個(gè)) select * from school.score scr left join school.student stu on scr.s_id= stu.s_id;[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-iLBiU3Dm-1616598779792)(…/TypoarWrokPath/images/1616208172898.png)]
3.右外連接 rigth join
--同理和left join相反,A right join B ,則顯示B表中所有的記錄,A表不足的用null填充 select * from score sco right join student stu on sco.s_id=stu.s_id;[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-g3YBRrJn-1616598779793)(…/TypoarWrokPath/images/1616207431665.png)]
4. full outer join 等價(jià) full join ,全外連接
--包含左、右兩個(gè)表的全部行,不管另外一邊的表中是否存在與它們匹配的行 在功能上,它等價(jià)于對(duì)這兩個(gè)數(shù)據(jù)集合分別進(jìn)行左外連接和右外連接,然后再使用消去重復(fù)行的并操作將上述兩個(gè)結(jié)果集合并為一個(gè)結(jié)果集。select * from score sco full join student stu on sco.s_id=stu.s_id;[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-XGmQFb4j-1616598779793)(…/TypoarWrokPath/images/1616208476647.png)]
6. left semi join 左半開連接 ,會(huì)顯示左半邊表中記錄,前提是其記錄對(duì)于右半邊表滿足于on語句中判定條件。
--只會(huì)顯示左半邊的表 select * from score sco left semi join student stu on sco.s_id=stu.s_id;[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-9rVAZGyb-1616598779795)(…/TypoarWrokPath/images/1616208655887.png)]
7.自連接是自身連接,指同一個(gè)表自己與自己進(jìn)行連接。這種一元連接通常用于從自反關(guān)系(也稱作遞歸關(guān)系)中抽取數(shù)據(jù)
select * from student stu inner join student stu1 on stu.s_id=stu1.s_id;[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-zYoUnmtj-1616598779795)(…/TypoarWrokPath/images/1616208844322.png)]
8.MAPJOIN
1. ,Hive中的Join可分為Common Join(Reduce階段完成join)和Map Join(Map階段完成join)
2.開啟join操作
set hive.auto.convert.join = true(默認(rèn)值)
運(yùn)行時(shí)自動(dòng)將連接轉(zhuǎn)換為MAPJOIN
MAPJOIN操作不支持:
1.在UNION ALL, LATERAL VIEW, GROUP BY/JOIN/SORT
BY/CLUSTER BY/DISTRIBUTE BY等操作后面
在UNION, JOIN 以及其他 MAPJOIN之前
34.排序
-執(zhí)行的先后順序
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-nQXlgyAh-1616598779797)(…/TypoarWrokPath/images/1616490147382.png)]
1.order by
全局排序 desc 降序 asc 升序 效率低
注意:使用 order by 全局只有一個(gè)reduce
每個(gè) Reduce內(nèi)部排序(Sort By)
Sort By:對(duì)于大規(guī)模的數(shù)據(jù)集 order by 的效率非常低。在很多情況下,并不需要全局排
序,此時(shí)可以使用 sort by。
Sort by 為每個(gè) reducer 產(chǎn)生一個(gè)排序文件。每個(gè) Reducer 內(nèi)部進(jìn)行排序,對(duì)全局結(jié)果集
來說不是排序。
1**)設(shè)置 reduce 個(gè)數(shù)
<font color='cornflowerblue'>hive (default)> set mapreduce.job.reduces=3; </font>2**)查看設(shè)置** reduce 個(gè)數(shù)
<font color='cornflowerblue'>hive (default)> set mapreduce.job.reduces; </font>3**)根據(jù)部門編號(hào)降序查看員工信息**
<font color='cornflowerblue'>hive (default)> select * from emp sort by deptno desc; </font>4**)將查詢結(jié)果導(dǎo)入到文件中(按照部門編號(hào)降序排序)**
hive (default)> insert overwrite local directory '/opt/module/data/sortby-result' --路徑不能存在select * from emp sort by deptno desc; -會(huì)在對(duì)應(yīng)的文件夾下面產(chǎn)生對(duì)應(yīng)的文件個(gè)數(shù)分區(qū)(Distribute By)
Distribute By: 在有些情況下,我們需要控制某個(gè)特定行應(yīng)該到哪個(gè) reducer,通常是為
了進(jìn)行后續(xù)的聚集操作。distribute by 子句可以做這件事。distribute by 類似 MR 中 partition
(自定義分區(qū)),進(jìn)行分區(qū),結(jié)合 sort by 使用。
對(duì)于 distribute by 進(jìn)行測(cè)試,一定要分配多 reduce 進(jìn)行處理,否則無法看到 distribute
by 的效果。
案例實(shí)操:
(1)先按照部門編號(hào)分區(qū),再按照員工編號(hào)降序排序。
hive (default)> set mapreduce.job.reduces=3;
hive (default)> insert overwrite local directory
‘/opt/module/data/distribute-result’ select * from emp distribute by
deptno sort by empno desc;
注意:
distribute by 的分區(qū)規(guī)則是根據(jù)分區(qū)字段的 hash 碼與 reduce 的個(gè)數(shù)進(jìn)行模除后,
余數(shù)相同的分到一個(gè)區(qū)。
Hive 要求 DISTRIBUTE BY 語句要寫在 SORT BY 語句之前。
6.4.6 Cluster By
當(dāng) distribute by 和 sorts by 字段相同時(shí),可以使用 cluster by 方式。
cluster by 除了具有 distribute by 的功能外還兼具 sort by 的功能。但是排序只能是升序
排序,不能指定排序規(guī)則為 ASC 或者 DESC。
(1)以下兩種寫法等價(jià)
hive (default)> select * from emp cluster by deptno;
hive (default)> select * from emp distribute by deptno sort by deptno;
注意:按照部門編號(hào)分區(qū),不一定就是固定死的數(shù)值,可以是 20 號(hào)和 30 號(hào)部門分到一
個(gè)分區(qū)里面去 有數(shù)據(jù)傾斜的現(xiàn)象
1.rank() over()
--成績(jī)相同的,并列名次,下一個(gè)名次空出被占用的名次 select name ,course ,score ,rank() over (partition by course order by score desc) rank from student ; --注意: 使用rank() over的時(shí)候,空值是最大的,如果排序字段為null,可能造成null字段排在最前面,影響排序結(jié)果。可以這樣:rank() over(partition by course order by score desc nulls last)來規(guī)避這個(gè)問題。[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-ByiMMNHf-1616598779798)(…/TypoarWrokPath/images/1616401421823.png)]
2.dense_rank() over()
--成績(jī)相同的,并列名次,下一個(gè)名次不空出被占用的名次 select name ,course ,score ,dense_rank() over (partition by course order by score desc) rank[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-Z3mno65B-1616598779801)(…/TypoarWrokPath/images/1616402138545.png)]
3.row_number over
--不管是否并列,都進(jìn)行連續(xù)排名 select name ,course ,score ,row_number() over(partition by course order by score desc) from student ;[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-0Yq8YRFl-1616598779802)(…/TypoarWrokPath/images/1616402688507.png)]
35.cast when 和 i f
--case when then else end 語法 --case sex when '男' then 1 else 0 end --解釋 當(dāng)sex的值等于男的時(shí)候就是1 否則就是0 end 就是退出 select dept_id,sum(case sex when '男' then 1 else 0 end) nan,sum(case sex when '女' then 1 else 0 end) nv from emp_sex group by dept_id;--多條件判斷 select dept_id,sum(case sex when '男' then 1 when '男' then 1 when '男' then 1 when '男' then 1 else 0 end) nan,sum(case sex when '女' then 1 else 0 end) nv from emp_sex group by dept_id;--if判斷 跟java的意思一樣的 --if(sex='男',1,0) 解釋 如果sex的值是男的就返回一,否則就返回0 select dept_id,sum(if(sex='男',1,0)) nan,sum(if(sex='女',1,0)) nv from emp_sex group by dept_id;SQL練習(xí)
--1.創(chuàng)建數(shù)據(jù)庫 create database school_qe;--創(chuàng)建課程表 create table COURSE (`CNO` string comment '課程編號(hào)', `CNAME` string comment '課程名稱,', `TNO` string comment '教師編號(hào)' ) row format delimited fields terminated by ',' ; --導(dǎo)入數(shù)據(jù) load data local inpath '/opt/data/COURSE.txt' into table course; --創(chuàng)建成績(jī)表 create table SCORE (`SNO` string comment '學(xué)生編號(hào)', `CNO` string comment '課程編號(hào)', `DEGREE` int comment '分?jǐn)?shù)' ) row format delimited fields terminated by ',' ; load data local inpath '/opt/data/SCORE.txt' into table SCORE; --創(chuàng)建學(xué)生表 create table Student (`SNO` string comment '學(xué)生編號(hào)', `SNAME` string comment '學(xué)生姓名', `SSEX` string comment '學(xué)生性別', `SBIRTHDAY` string comment '出生年月', `CLASS` string comment '班級(jí)' ) row format delimited fields terminated by ',' ; load data local inpath '/opt/data/STUDENT.txt' into table Student; --創(chuàng)建老師表create table TEACHER (`TNO` string comment '教師編號(hào)', `TNAME` string comment '教師姓名', `TSEX` string comment '性別', `TBIRTHDAY` string comment '出生年月', `PROF` string comment '職稱', `DEPART` string comment '課程' )row format delimited fields terminated by ',' ; load data local inpath '/opt/data/TEACHER.txt' into table TEACHER; --2.練習(xí) --1、查詢Score表中成績(jī)?cè)?0到80之間的所有記錄 select * from score where degree between 60 and 80; --2、查詢Score表中成績(jī)?yōu)?5,86或88的記錄 select * from score where degree in(85,86,88); --3、以Cno升序、Degree降序查詢Score表的所有記錄。 select * from score order by cno asc,degree desc; --4、查詢Score表中的最高分的學(xué)生學(xué)號(hào)和課程號(hào)。 --1.第一種方式 使用order by 進(jìn)行分組 SELECT a.sno,a.cno from ( SELECT * FROM score ORDER BY degree DESC LIMIT 1 ) a ; --第二種方式 使用 sort by 進(jìn)行排序 select a.sno,a.cno from ( select * from score sort by degree desc limit 1 ) a ; --5、查詢Score表中至少有5名學(xué)生選修的并以3開頭的課程的平均分?jǐn)?shù)。select cno,avg(degree) from scorewhere cno like'%3%'group by cnohaving count(cno) >=5; --6、查詢最低分大于70,最高分小于90的Sno列。 SELECT sno FROM score GROUP BY sno HAVING min(degree) >70 and max(degree)<90 --7、查詢所有學(xué)生的Sname、Cno和Degree列 SELECT stu.sname,sco.degree,sco.cno FROM score sco JOIN student stu on sco.sno = stu.sno --8、查詢“95033”班所選課程的平均分。 with s_is as (select sno from student where class ='95033')select avg(sco.degree) from score sco ,s_is ss where sco.sno in(ss.sno) ;基金sql題目
create table jijin(jijin_code string,jijin_time string,jijin_bcode string ) row format delimited fields terminated by ',' ;load data local inpath '/opt/data/jijin.txt' into table jijin;36.聚合運(yùn)算
1.GROUP BY用于分組
Hive基本內(nèi)置聚合函數(shù)與GROUP BY一起使用
如果沒有指定GROUP BY子句,則默認(rèn)聚合整個(gè)表
除聚合函數(shù)外,所選的其他列也必須包含在GROUP BY中
GROUP BY支持使用CASE WHEN或表達(dá)式
支持按位置編號(hào)分組
set hive.groupby.orderby.position.alias=true;
Hive****聚合運(yùn)算 - GROUP BY
select category, max(offervalue) from offers group by category;
– group by使用表達(dá)式
select if(category > 4000, ‘GOOD’, ‘BAD’) as newcat,max(offervalue)
from offers group by category if(category > 4000, ‘GOOD’, ‘BAD’);
解釋: 如果 category 大于4000 就是GOOD 否則就是 BAD group by 根據(jù)if 里面的判斷 大于4000 就根據(jù)GOOD進(jìn)行
分組,小于4000就根據(jù)BAD 進(jìn)行分組
2.Hive聚合運(yùn)算 - HAVING
HAVING:對(duì)GROUP BY聚合結(jié)果的條件過濾
可以避免在GROUP BY之后使用子查詢
HAVING之后可以使用表達(dá)式,不建議
--having使用 select sex_age.age from employee group by sex_age.age having count(*) <= 1; --使用子查詢代替having 不建議使用 select a.age from ( select count(*) as cnt, sex_age.age from employee group by sex_age.age ) a where a.cnt <= 1;模擬面試:having 和 where有什么不同?
having 和where 都是進(jìn)行篩選的,
但是having 是對(duì)于 分組之后的數(shù)據(jù)進(jìn)行刪除, having 一定要和 group by 一起使用 但是group by 可以單獨(dú)使用
而 其他篩選就使用 where 進(jìn)行篩選
37.窗口函數(shù)
1.窗口函數(shù)是一組特殊函數(shù)
掃描多個(gè)輸入行來計(jì)算每個(gè)輸出值,為每行數(shù)據(jù)生成一行結(jié)果
可以通過窗口函數(shù)來實(shí)現(xiàn)復(fù)雜的計(jì)算和聚合
38.函數(shù)
函數(shù)三大類型
1.UDF:一進(jìn)一出
2.UDAF:多進(jìn)一出
3.UDTF:一進(jìn)多出
解釋:一和多指的是輸入數(shù)據(jù)的行數(shù)
1.系統(tǒng)內(nèi)置函數(shù)
查看系統(tǒng)自帶的函數(shù)
show functions;顯示自帶的函數(shù)的用法
desc function upper;詳細(xì)顯示自帶的函數(shù)的用法
desc function extended upper;2.空字段賦值
函數(shù)說明
NVL:給值為 NULL 的數(shù)據(jù)賦值,它的格式是 NVL( value,default_value)。它的功能是如
果 value 為 NULL,則 NVL 函數(shù)返回 default_value 的值,否則返回 value 的值,如果兩個(gè)參數(shù)
都為 NULL ,則返回 NULL
--如果comm的這一列的值有空的就用-1來填充 select comm,nvl(comm, -1) from emp;3.小案列
1.準(zhǔn)備數(shù)據(jù)
悟空 A 男 大海 A 男 宋宋 B 男 鳳姐 A 女 婷姐 B 女 婷婷 B 女2.需求
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-2PubwnW1-1616598779803)(…/TypoarWrokPath/images/1616596401989.png)]
3.步驟
selectdept_id,sum(case sex when '男' then 1 else 0 end) male_count, --使用if進(jìn)行判斷,然后進(jìn)行累加sum(case sex when '女' then 1 else 0 end) female_count --使用if進(jìn)行判斷,然后進(jìn)行累加 from emp_sex group by dept_id; --對(duì)部門進(jìn)行分組re 都是進(jìn)行篩選的,
但是having 是對(duì)于 分組之后的數(shù)據(jù)進(jìn)行刪除, having 一定要和 group by 一起使用 但是group by 可以單獨(dú)使用
而 其他篩選就使用 where 進(jìn)行篩選
37.窗口函數(shù)
1.窗口函數(shù)是一組特殊函數(shù)
掃描多個(gè)輸入行來計(jì)算每個(gè)輸出值,為每行數(shù)據(jù)生成一行結(jié)果
可以通過窗口函數(shù)來實(shí)現(xiàn)復(fù)雜的計(jì)算和聚合
38.函數(shù)
函數(shù)三大類型
1.UDF:一進(jìn)一出
2.UDAF:多進(jìn)一出
3.UDTF:一進(jìn)多出
解釋:一和多指的是輸入數(shù)據(jù)的行數(shù)
1.系統(tǒng)內(nèi)置函數(shù)
查看系統(tǒng)自帶的函數(shù)
show functions;顯示自帶的函數(shù)的用法
desc function upper;詳細(xì)顯示自帶的函數(shù)的用法
desc function extended upper;2.空字段賦值
函數(shù)說明
NVL:給值為 NULL 的數(shù)據(jù)賦值,它的格式是 NVL( value,default_value)。它的功能是如
果 value 為 NULL,則 NVL 函數(shù)返回 default_value 的值,否則返回 value 的值,如果兩個(gè)參數(shù)
都為 NULL ,則返回 NULL
--如果comm的這一列的值有空的就用-1來填充 select comm,nvl(comm, -1) from emp;3.小案列
1.準(zhǔn)備數(shù)據(jù)
悟空 A 男 大海 A 男 宋宋 B 男 鳳姐 A 女 婷姐 B 女 婷婷 B 女2.需求
[外鏈圖片轉(zhuǎn)存中…(img-2PubwnW1-1616598779803)]
3.步驟
selectdept_id,sum(case sex when '男' then 1 else 0 end) male_count, --使用if進(jìn)行判斷,然后進(jìn)行累加sum(case sex when '女' then 1 else 0 end) female_count --使用if進(jìn)行判斷,然后進(jìn)行累加 from emp_sex group by dept_id; --對(duì)部門進(jìn)行分組總結(jié)
- 上一篇: 计算机主机后面辐射大,电脑的背面辐射大吗
- 下一篇: 巨无霸Win8PE X64服务器维护专用