Hive UDF用于选择除某些列

时间:2015-07-28 03:30:30

标签: apache-spark hive hiveql apache-spark-sql udf

HiveQL(以及一般的SQL)中的常见查询构建模式是选择所有列(SELECT *)或显式指定的列集(SELECT A, B, C)。 SQL没有内置机制来选择除指定的列集之外的所有列。

this SO question中列出了排除某些列的各种机制,但没有一种适用于HiveQL。 (例如,创建一个临时表SELECT *然后ALTER TABLE DROP某些列的想法会在大数据环境中造成严重破坏。)

忽略关于选择除了某些列之外的所有列是否是一个好主意的意识形态讨论,这个问题是关于使用此功能扩展Hive的可能方法。

在Hive 0.13.0之前,SELECT可以使用基于正则表达式的列,例如,在反引号引用的字符串中使用property_.*。 @ invoketheshell的答案在下面引用了这个功能,但它是有代价的,即当启用此功能时,Hive不能接受其中包含非标准字符的列,例如$foo或{ {1}}。这就是Hive开发人员默认情况下在0.13.0中关闭此行为的原因。我正在寻找适用于任何列名称的通用解决方案。

生成泛型表的UDF(UDTF)当然可以这样做,因为它可以manipulate the schema。由于我们不打算生成新行,有没有办法使用简单的基于行的UDF来解决这个问题?

这似乎是网络上很多帖子的常见问题,显示如何为各种数据库解决这个问题,但我还没能找到Hive的解决方案。是否有代码可以执行此操作?

1 个答案:

答案 0 :(得分:8)

您可以选择除基于正则表达式的规范中列出的列之外的所有列。这是排除的查询列。见下文:

SELECT语句可以在0.13.0之前的Hive版本中使用基于正则表达式的列规范,如果配置属性hive.support.quoted.identifiers设置为none,则可以在0.13.0及更高版本中使用。

话虽如此,您可以使用以下内容创建新表或视图,并且将返回除指定列之外的所有列:

hive.support.quoted.identifiers=none;    

drop table if       exists database.table_name;
create table if not exists database.table_name as
    select `(column_to_remove_1|...|column_to_remove_N)?+.+`
    from database.some_table
    where 
    --...
;

这将创建一个表,其中包含some_table中的所有列,但名为column_to_remove_1,...,列到column_to_remove_N的列除外。您也可以选择创建视图。