在 Athena 中,如何在结构中的数组中查询结构的成员?

Posted

技术标签:

【中文标题】在 Athena 中,如何在结构中的数组中查询结构的成员?【英文标题】:In Athena how do I query a member of a struct in an array in a struct? 【发布时间】:2020-01-14 15:23:39 【问题描述】:

在创建以下表格的情况下,我试图弄清楚如何查询我在哪里检查 usage 的值:

CREATE EXTERNAL TABLE IF NOT EXISTS foo.test (
     `id` string,
     `foo` struct< usages:array< struct< usage:string,
     method_id:int,
     start_at:string,
     end_at:string,
     location:array<string> >>> 
) PARTITIONED BY (
         timestamp date 
) 
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
WITH SERDEPROPERTIES (
         'serialization.format' = '1' ) LOCATION 's3://foo.bar/' TBLPROPERTIES ('has_encrypted_data'='false');

我想要这样的查询:

SELECT * FROM "foo"."test" WHERE foo.usages.usage is null;

当我这样做时,我得到:

SYNTAX_ERROR:第 1:53 行:表达式 "foo"."usages" 不是 ROW 类型

如果我在直接索引数组的地方进行查询,如下所示,它可以工作。

SELECT * FROM "foo"."test" WHERE foo.usages[1].usage is null;

不过,我的总体目标是查询 usages 数组中的所有项目,并找到 usages 数组中至少一个项目的成员 usage 为空的任何行。

【问题讨论】:

【参考方案1】:

您可以通过将数组取消嵌套到行中来实现此目的,然后检查这些行中的 null 值。这将导致每个 null-value 条目有一行。

select * from test
CROSS JOIN UNNEST(foo.usages) AS t(i)
where i.usage is null

因此,如果您只需要唯一集,则必须通过 select distinct 运行它。

select distinct id from test
CROSS JOIN UNNEST(foo.usages) AS t(i)
where i.usage is null

【讨论】:

我的直觉表明 UNNEST+DISTINCT 不会是最高效的选项。即使 Athena 获得了 UNNEST 优化 (github.com/prestosql/presto/pull/901),对于更大的数据集,DISTINCT 的成本可能仍然很高。【参考方案2】:

Athena 基于 Presto。在 Presto 318 中你可以使用any_match:

SELECT * FROM "foo"."test"
WHERE any_match(foo.usages, element -> element.usage IS NULL);

我认为该功能在 Athena 中尚不可用,但您可以使用 reduce 模拟它。

SELECT * FROM "foo"."test"
WHERE reduce(
  foo.usages, -- array to reducing
  false, -- initial state
  (state, element) -> state OR element.usage IS NULL, -- combining function
  state -> state); -- output function (identity in this case)

【讨论】:

确实any_match在雅典娜中不可用 这个 reduce 需要一个小的改动才能为我工作......我不得不用 OR 关键字替换 ||(否则它会将其视为数组连接运算符) @Anentropic 对!.. 每天都有太多 Java。已更新,谢谢。 any_match 仍然不可用。有关 Athena 中所有可用 Presto 功能的列表:docs.aws.amazon.com/athena/latest/ug/presto-functions.html

以上是关于在 Athena 中,如何在结构中的数组中查询结构的成员?的主要内容,如果未能解决你的问题,请参考以下文章

在查询athena时将结构转换为json

Athena/Presto:复杂结构/数组

Athena 嵌套结构查询 - 如何在 SQL 中查询 Value_counts

aws athena & java - 在结构类型列中获取数据

有没有办法在 AWS Athena 中展平结构字段?

AWS Athena 将结构数组导出到 JSON