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.mzph.cn/news/280140.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.Net+MySQL组合开发(二) 数据访问篇

一、建立数据库、表、添加数据这里我们使用图形化操作的SQL Manager 2005 Lite for MySQL来建立数据,它的操作界面非常类似OFFICE软件,使用方便、很容量上手、下面开始建立数据库及表单击"Creat New DataBase":新建DB输入密码&…

Git vs SVN

一、Git vs SVN Git 和 SVN 孰优孰好,每个人有不同的体验。Git是分布式的,SVN是集中式的这是 Git 和 SVN 最大的区别。若能掌握这个概念,两者区别基本搞懂大半。因为 Git 是分布式的,所以 Git 支持离线工作,在本地可以…

Burpsuite学习(4)

2019独角兽企业重金招聘Python工程师标准>>> burpsuite spider模块通过跟踪 HTML 和 JavaScript 以及提交的表单中的超链接来映射目标应用程序,它还使用了一些其他的线索,如目录列表,资源类型的注释,以及 robots.txt 文…

Git删除分支/恢复分支

这是https://www.cnblogs.com/utank/p/7880441.html的方法,虽然很老现在有点不一样,但总体还是能用的。 总结就是两种方法 1.用commit的id恢复 2.用reflog的头指针恢复 •删除一个已被终止的分支 如果需要删除的分支不是当前正在打开的分支,使…

NetCore2.0Web应用之Startup

为什么80%的码农都做不了架构师?>>> 作为main函数的程序启动文件UseStartup 默认就是调用我们的整个应用程序的启动文件 class Program{static void Main(string[] args){var host new WebHostBuilder().UseKestrel() // 指定WebServer为Kes…

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…

03 Oracle分区表

Oracle分区表 先说句题外话… 欢迎成都天府软件园的小伙伴来面基交流经验~ 一:什么是分区(Partition)? 分区是将一个表或索引物理地分解为多个更小、更可管理的部分。 分区对应用透明,即对访问数据库的应用而言&…

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 …

如何解决高并发,秒杀问题

相信不少人会被这个问题困扰,分享大家一篇这样的文章,希望能够帮到你! 一、秒杀业务为什么难做?1)im系统,例如qq或者微博,每个人都读自己的数据(好友列表、群列表、个人信息&#xf…

Spring原理之代理与动态代理模式总结(四)

2019独角兽企业重金招聘Python工程师标准>>> 代理模式 1,什么是代理模式? 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。2,代理模式有什么好处? 在某些情况下,一个客户不…

可执行文件添加快捷方式_如何停止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…

看明星合影争C位,学PPT中C位排版法

在娱乐圈里,C位是大咖位,是对艺人实力的最好证明,艺人们自然会想着去力争C位,正所谓“不想当将军的兵不是好兵,不想站C位的明星不是好明星”。那么,C位是什么意思?C位,网络流行语&am…

javafx由浅到深的 认识(一)

javafx是一款比较新兴的语言框架,随着javafx越来越实用,估计许多程序员也会慢慢接触它,故我在这里对它由浅到深进行介绍一下. 首先,要了解javafx,就应该先知道.xml文件的布局软件,以往java都是通过敲代码来进行布局的,但javafx有力新的突破,它实现了拖动方式,目前我使用的辅助软…

linux用户的根目录_为什么Linux允许用户删除根目录?

linux用户的根目录Most of the time, none of us willingly performs an action that will literally break our operating systems and force us to reinstall them. But what if such an action could easily occur even by accident on the user’s part? Today’s SuperUs…

微软跨平台maui开发chatgpt客户端

image什么是maui.NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架,用于使用 C# 和 XAML 创建本机移动(ios,andriod)和桌面(windows,mac)应用。imagechagpt最近这玩意很火,由于网页版本限制了ip,还得必须开代理, 用起来比较麻烦&a…

在Xshell 6开NumLock时按小键盘上的数字键并不能输入数字

小键盘问题 在Xshell 6上用vi的时候,开NumLock时按小键盘上的数字键并不能输入数字,而是出现一个字母然后换行(实际上是命令模式上对应上下左右的键)。解决方法 选项Terminal->Features里,找到Disable application …

chrome 固定缩放比例_您如何调整Google Chrome浏览器的用户界面缩放比例?

chrome 固定缩放比例Everything can be going along nicely until a program gets a new update that suddenly turns everything into a visual mess, like scaling up the UI, for example. Is there a simple solution? Today’s SuperUser Q&A post has some helpful …

优雅告别 2022 年,2023 年主题:敢想,就敢做!

自从工作之后,每年春节我都会花一天时间,一个人待在一个小房间,思考自己今年做了什么具备阶段性成果的事情。然后,写下明年需要执行的计划。会写在一个 XMind 文件里,记录每一年将要执行的计划,且未完成的计…

java发送gmail_如何在Gmail中轻松通过电子邮件发送人群

java发送gmailMailing lists are an old tool in the email arsenal, but their implementation in Gmail isn’t immediately intuitive. Read on as we show you how to email groups using your Gmail account. 邮件列表是电子邮件库中的一个旧工具,但是在Gmail中…

Asp.net MVC使用Model Binding解除Session, Cookie等依赖

上篇文章"Asp.net MVC使用Filter解除Session, Cookie等依赖"介绍了如何使用Filter来解除对于Session, Cookie的依赖。其实这个也可以通过Model Binding来达到同样的效果。 什么是Model Binding? Model Binding的作用就是将Request请求中包含的散乱参数,根…