前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在shell中使用hiveSQL的注意事项

在shell中使用hiveSQL的注意事项

作者头像
超哥的杂货铺
发布2021-01-14 11:04:52
1.4K0
发布2021-01-14 11:04:52
举报
文章被收录于专栏:超哥的杂货铺超哥的杂货铺
概述

hive是数据分析人员常用的工具之一。实际工作中,使用hive基本都是在linux shell环境下。运行hiveSQL的方式有以下几种。

1.hive 交互式命令行

即在shell环境下直接使用hive命令,当屏幕下方出现hive>时,就进入了hive的环境,如下图所示。在>后面就可以写hiveSQL查询我们需要的数据,注意语句之间用英文分号隔开。通常适合于语句较短,需要快速查询或者对大段SQL进行语法调试的情况。

2.hive -e方式

hive -e "待执行sql"。这种方式允许我们在引号中写入需要执行的SQL语句。通常适合于语句较长的情况。这种方式也是在需要进行任务调度时采用的最直接方式,此时可以结合shell定义可变参数(如日期),再结合调度系统就可以实现脚本自动化。

3.hive -f方式

这种方式类似于前一种,区别把待执行sql预先写入到一个文件,采用hive -f sql文件来执行。在任务调度时也可以采用,但由于需要跨文件处理,相对而言,hive -e更为直接。

以上我们总结了hiveSQL常见的运行方式。下面再来看一些实际使用时一些可能会忽略的点。为方便讨论,我们构造以下数据,测试表名为test_0102

hive -e遇到竖线分割时,要加多个转义符

先来看交互式命令行的方式。

假设我们要取出每个用户的城市和性别,使用split函数,可能会采用以下写法:

代码语言:javascript
复制
select 
split(location_city, '|')[0] as city,
split(location_city, '|')[1] as gender
from test_0102;

结果如下图所示。

显然结果不是我们想要的,这是因为竖线比较特殊。我们加上转义符再来看下。

结果并未发生变化,不符合预期。如果再加一个转义符。

可以看到这样才最终得到了我们想要的结果。这是因为:第一个转义符是从 hive -> MapReduce 过程的转义第二个转义符是 MapReduce 编译时的转义。

再来看使用hive -e的方式执行。如果直接用两个转义符,输出的结果仍然是把单字分隔开。

所以我们再加一个转义符,看到正确分割出了结果,如下图所示。

这是因为从shell到hive多了一步转义。因此需多加一个转义符。实际上,如果使用四个转义符,结果依然正确。个人认为实际中我们可以不用过多关注每一步转义到底因为什么,但当遇到正则表达式或者split时,要多多留心特殊字符。最好用一个简单例子测试一下,避免数据不符合预期。下面这个链接对转义有比较深入分析,建议仔细阅读。

参考链接:https://blog.csdn.net/lt793843439/article/details/91492088

相应的,如果遇到双竖线的情况,对每一个竖线则需要分别转义。例如我们要将上面数据中skills一列分割出来。相应写法如下

  • hive命令行:每一个竖线两个转义符
  • hive -e:每一个竖线三个转义符(四个也行)
hive -e 生成结果文件时,文件名要和重定向符放在一行

hive -e执行hiveSQL时,可以采用重定向符(>)把查询结果写入文件。

代码语言:javascript
复制
hive -e"
use dac_twelve_dev;
select 
split(location_city, '\\\|')[0] as city,
split(location_city, '\\\|')[1] as gender
from test_0102;" > test_0102.txt

cat test_0102.txt
北京  男
上海  女
北京  男
广州  女
西安  男

需要注意的是,结尾的双引号,重定向符号,结果文件文件名和要放在同一行。否则则可能不能如期生成结果文件。如下面几种方式所示。

代码语言:javascript
复制
#第一种
hive -e"
your SQL
" > 
test_0102.txt

#第二种
hive -e"
your SQL" 
> 
test_0102.txt

#第三种
hive -e"
your SQL" 
> test_0102.txt

上面的三种方式,第一种会报错:-bash: syntax error near unexpected token `newline。第二种会在屏幕上打印结果后报相同的错,第三种会在屏幕上打印结果不报错,但最终结果文件没有数据。

shell中执行hiveSQL打印SQL时注意星号

在调度中运行hiveSQL时,一般会使用shell脚本文件。脚本中先定义好时间变量,再定义SQL语句,最后使用hive -e方式执行SQL。类似于下面这样:

代码语言:javascript
复制
yesterday=`date -d "now -1 day" +%Y-%m-%d`
hql="
select * from xxt_able where ds='${yesterday}'
"
echo $hql#错误的写法,正确的是echo "$hql"
hive -e $hql > result.txt

这里需要注意的是如果定义的hql语句中有*号(等特殊符号),为了在echo打印时能够正常输出,以便于我们核查时间变量是否被正确替换。需要用"

关于hive执行时的其他选项
  • -S选项屏蔽mapreduce日志

执行hiveSQL时,如果需要执行MapReduce过程,屏幕上会出现类似于map=100%,reduce=33%这样的提示,如果任务比较复杂,日志长度也会相应增加。虽然能便于我们了解任务进度,但有时我们也会想把它屏蔽掉。使用hive -S -e "sql语句"的方式,以Silent mode运行hive,就可以实现这样的目,此时屏幕上只会有hive启动的日志,而不会有mapreduce过程的日志。

  • -v选项打印出实际执行的SQL

这个选项可以用于前面提到的任务调度时,验证实际执行的详细SQL。假设我们提前定义好yesterday变量,-v选项会将变量值打印出来,也就替代了echo "$hql"的方式。(这里SQL报错了,我们为了演示变量,引用了表中不存在的ds字段)

  • hive执行结果显示表头

set hive.cli.print.header=true;默认hive查询的结果时没有列名(表头)的,如果想要在结果中显示,可以在sql语句前加上这个选项,就可以显示列名了。

  • hive关闭严格模式

set hive.mapred.mode=nonstrict;hive执行模式有严格和非严格之分。通常,hive严格模式禁止三种查询:

1.对于分区表,必须指定分区,否则会报错No parttion predicate found for Alias xxx Table xxx.

2.使用了order by,则必须使用limit。提示信息为In strict mode,if ORDER BY is specified ,LIMIT must also be specifiied.

3.禁止笛卡尔积查询。提示信息为:In strict mode, cartesian product is not allowed.

使用这个设置关闭严格模式,可以使查询更灵活。

小结

本文总结了实际工作中使用hive的一些容易被忽略的注意事项。包括转义符,*号等特殊字符,结果文件生成,以及一些有用的选项和设置。此外,使用hive -h能看到其他的一些hive选项。掌握它们能够避免不必要的麻烦,起到事半功倍的效果。后台回复"hive"获取本文pdf版本。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 超哥的杂货铺 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • hive -e遇到竖线分割时,要加多个转义符
  • hive -e 生成结果文件时,文件名要和重定向符放在一行
  • shell中执行hiveSQL打印SQL时注意星号
  • 关于hive执行时的其他选项
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档