Products
GG网络技术分享 2025-03-18 16:09 0
Hive SQL 几乎是每一位互联网分析师的必备技能,相信每一位面试过大厂的童鞋都有被面试官问到 Hive 优化问题的经历。所以掌握扎实的 HQL 基础尤为重要,既能帮分析师在日常工作中如鱼得水提高效率,也能在跳槽时获得一份更好的工作 offer。
本篇为 Hive 入门篇,主要为 Hive SQL 基础语法介绍,文章争取做到言简意赅,让大家 30 分钟入门 HQL。
文中视角多处 HQL 对比 关系型数据库 SQL,适合有一定 SQL 基础的童鞋。(未掌握基础 SQL 童鞋请移步「w3c school - SQL」快速上手 SQL)
---------- Hive 优化篇敬请期待
简单来说,Hive 是基于 Hadoop 的一个数据仓库工具。
Hive 的计算基于 Hadoop 实现的一个特别的计算模型 MapReduce,它可以将计算任务分割成多个处理单元,然后分散到一群家用或服务器级别的硬件机器上,降低成本并提高水平扩展性。
Hive 的数据存储在 Hadoop 一个分布式文件系统上,即 HDFS。
需明确的是,Hive 作为数仓应用工具,对比 RDBMS(关系型数据库) 有3个不能:
另外,Hive 相比 RDBMS 是一个更宽松的世界,比如:
Hive select 常规语法与 Mysql 等 RDBMS SQL 几乎无异,下面附注语法格式,具体不做详细讲解。本节重点介绍 Hive 中出现的一些比较特殊且日常中我有用到的一些技巧给到大家参考。
2.1 附注 select 语法及语序,
SELECT[ALL|DISTINCT] select_expr, select_expr, ...FROMtable_reference[WHEREwhere_condition]
[GROUPBYcol_list]
[ORDERBYorder_condition]
[DISTRIBUTEBYdistribute_condition [SORTBYsort_condition] ]
[LIMITnumber]
2.2 多维度聚合分析 grouping sets/cube/roolup,
以一个示例来说明 3者作用及区别。request 表为后端请求表,现需分别统计3种不同维度的聚合:总共多少请求?不同系统、设备多少请求?不同城市多少请求。
不使用多维聚合方法,
SELECTNULL,NULL,NULL,COUNT(*)FROMrequestsUNIONALLSELECTos, device,NULL,COUNT(*)FROMrequestsGROUPBYos, deviceUNIONALLSELECTnull,null, city,COUNT(*)FROMrequestsGROUPBYcity;
使用 grouping sets,
SELECTos, device, city ,COUNT(*)FROMrequestsGROUPBYos, device, cityGROUPINGSETS((os, device), (city), ());
cube 会枚举指定列的所有可能组合作为 grouping sets,而 roolup 会以按层级聚合的方式产生 grouping sets。如,
GROUPBYCUBE(a, b,c) --等价于以下语句。GROUPINGSETS((a,b,c),(a,b),(a,c),(b,c),(a),(b),(c),())GROUPBYROLLUP(a, b,c)
--等价于以下语句。GROUPINGSETS((a,b,c),(a,b),(a), ())
2.3 正则方法指定 select 字段列
说是指定,其实是排除,如:`(num|uid)? . ` 排除 num 和 uid 字段列。
另外,where 使用正则可以如此:where A Rlike B、where A Regexp B。
2.4 Lateral View(一行变多行)
Lateral View 和表生成函数(例如Split、Explode等函数)结合使用,它能够将一行数据拆成多行数据,并对拆分后的数据进行聚合。
假设您有一张表pageAds,它有两列数据,第一列是pageid string,第二列是adid_list,即用逗号分隔的广告ID集合。
现需要统计所有广告在所有页面的出现次数,则先用 Lateral View explode 做处理,即可正常分组聚合统计。
SELECTpageid, adidFROMpageAdsLATERALVIEWexplode(adid_list) adTableASadid;
2.5 窗口函数
Hive 的窗口函数非常丰富,这在很多 RDBMS 中是少见的。(至少在 mysql 的较早期版本一直没有支持窗口函数,一个分组排序得用上非常复杂的 SQL 自定义变量)
其中最常用的窗口函数当属 row_number() over(partition by col order col_2),它可以实现按指定字段的分组排序。
其它更丰富的窗口函数,我这不赘述,篇幅太大,完全可以重开一篇新的文章。建议参考阿里云 MaxCompute 的这份「窗口函数」的文档,写得非常详细,强烈推荐!
witht1as(selectuser_idfromuserwhere...)
@var:=selectshop_idfromshopwhere...;select*fromuser_shopwhereuser_idin(select*fromt1)andshop_idin(select*from@var);
3.1 Hive 建表语句格式,
方法一:独立声明
CREATE[EXTERNAL]TABLE[IFNOTEXISTS] table_name[(col_name data_type [DEFAULTvalue] [COMMENTcol_comment], ...)]
[COMMENTtable_comment]
[PARTITIONEDBY(col_name data_type [COMMENTcol_comment], ...)]
[CLUSTEREDBY(col_name [, col_name, ...]) [SORTEDBY(col_name [ASC|DESC] [, col_name [ASC|DESC] ...])]INTOnumber_of_buckets BUCKETS]
[STOREDBYStorageHandler]-- 仅限外部表[WITHSERDEPROPERTIES (Options)]-- 仅限外部表[LOCATION OSSLocation];-- 仅限外部表[LIFECYCLE days]
[AS select_statement]
方法二:从已有表直接复制
CREATETABLE[IFNOTEXISTS] table_nameLIKEexisting_table_name
下面对当中关键的声明语句做解释:
简单示例:创建表sale_detail来保存销售记录,该表使用销售时间 sale_date 和销售区域 region 作为分区列。
createtableifnotexistssale_detail(
shop_namestring,
customer_idstring,
total_pricedouble)
partitionedby(sale_datestring, regionstring);
创建成功的表可以通过 desc 查看定义信息,
desc
Demand feedback