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,一经查实,立即删除!

相关文章

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;通过定量对比的方式来证明这一点。实验…