28

再次缺少 Hive 文档:

我想将查询结果以及列名写入本地文件。

Hive 支持这个吗?

Insert overwrite local directory 'tmp/blah.blah' select * from table_name;

另外,单独的问题:StackOverflow 是获得 Hive 帮助的最佳场所吗?@Nija,非常有帮助,但我不会一直打扰他们......

4

7 回答 7

64

尝试

set hive.cli.print.header=true;
于 2011-11-26T20:28:33.150 回答
15

是的你可以。将其放入set hive.cli.print.header=true;.hiverc目录或任何其他 hive 用户属性文件中的文件中。

模糊警告:小心,因为这在过去曾使我的查询崩溃(但我不记得原因)。

于 2012-10-10T18:38:10.043 回答
9

确实,@nija 的回答是正确的——至少据我所知。insert overwrite into [local] directory ...在执行(无论您是否使用本地)时,没有任何方法可以编写列名。

关于@user1735861 描述的崩溃,hive 中有一个已知的错误0.7.1(在 中修复0.8.0),在执行之后set hive.cli.print.header=true;,会导致NullPointerException任何 HQL 命令/查询不产生任何输出。例如:

$蜂巢-S
蜂巢>使用默认值;
蜂巢> 设置 hive.cli.print.header=true;
蜂巢>使用默认值;
线程“主”java.lang.NullPointerException 中的异常
    在 org.apache.hadoop.hive.cli.CliDriver.processCmd(CliDriver.java:222)
    在 org.apache.hadoop.hive.cli.CliDriver.processLine(CliDriver.java:287)
    在 org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:517)
    在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    在 java.lang.reflect.Method.invoke(Method.java:616)
    在 org.apache.hadoop.util.RunJar.main(RunJar.java:197)

虽然这很好:

$蜂巢-S
蜂巢> 设置 hive.cli.print.header=true;
蜂巢>从双重中选择*;
C
C
蜂巢>

非 HQL 命令虽然 ( set, dfs !, 等等...)

更多信息:https ://issues.apache.org/jira/browse/HIVE-2334

于 2012-10-26T15:04:34.127 回答
7

Hive 确实支持写入本地目录。你的语法看起来也很合适。
查看有关 SELECTS 和 FILTERS 的文档以获取更多信息。

我认为 Hive 没有办法将列的名称写入您正在运行的查询的文件中。. . 我不能肯定地说它没有,但我不知道有什么办法。

对于 Hive 问题,我认为唯一比 SO 更好的地方是邮件列表

于 2011-04-14T02:28:15.630 回答
4

我今天遇到了这个问题,并且能够通过在原始查询和创建标题行的新虚拟查询之间执行 UNION ALL 来获得所需的内容。我在每个部分添加了一个排序列,并将标题设置为 0,将数据设置为 1,这样我就可以按该字段排序并确保标题行排在最前面。

create table new_table as
select 
  field1,
  field2,
  field3
from
(
  select
    0 as sort_col,  --header row gets lowest number
    'field1_name' as field1,
    'field2_name' as field2,
    'field3_name' as field3
  from
    some_small_table  --table needs at least 1 row
  limit 1  --only need 1 header row
  union all
  select
    1 as sort_col,  --original query goes here
    field1,
    field2,
    field3
  from
    main_table
) a
order by 
  sort_col  --make sure header row is first

它有点笨重,但至少您可以通过单个查询获得所需的内容。

希望这可以帮助!

于 2014-08-09T01:40:30.170 回答
3

不是一个很好的解决方案,但这是我所做的:

create table test_dat
ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t" STORED AS 
INPUTFORMAT "com.hadoop.mapred.DeprecatedLzoTextInputFormat" 
OUTPUTFORMAT "org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat" 
LOCATION '/tmp/test_dat' as select * from YOUR_TABLE;

hive -e 'set hive.cli.print.header=true;select * from YOUR_TABLE limit 0' > /tmp/test_dat/header.txt

cat header.txt 000* > all.dat
于 2013-03-20T17:19:36.883 回答
2

这是我的看法。注意,我不是很精通 bash,所以欢迎提出改进建议 :)

#!/usr/bin/env bash

# works like this:
# ./get_data.sh database.table > data.csv

INPUT=$1
TABLE=${INPUT##*.}
DB=${INPUT%.*}

HEADER=`hive -e "
  set hive.cli.print.header=true;
  use $DB;
  INSERT OVERWRITE LOCAL DIRECTORY '$TABLE'
  row format delimited
  fields terminated  by ','
  SELECT * FROM $TABLE;"`

HEADER_WITHOUT_TABLE_NAME=${HEADER//$TABLE./}
echo ${HEADER_WITHOUT_TABLE_NAME//[[:space:]]/,}
cat $TABLE/*
于 2018-03-13T15:17:04.190 回答