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

NSA*_*NSA 3 sql json presto amazon-athena

我试图弄清楚如何查询我在哪里检查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');
Run Code Online (Sandbox Code Playgroud)

我想有一个查询,如:

SELECT * FROM "foo"."test" WHERE foo.usages.usage is null;
Run Code Online (Sandbox Code Playgroud)

当我这样做时,我得到:

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

如果我在直接索引数组的位置进行查询,如下所示。

SELECT * FROM "foo"."test" WHERE foo.usages[1].usage is null;
Run Code Online (Sandbox Code Playgroud)

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

Pio*_*sen 5

Athena 基于 Presto。在 Presto 318 中,您可以使用any_match

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

我认为该功能在 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)
Run Code Online (Sandbox Code Playgroud)

  • `any_match` 仍然不可用。有关 Athena 中所有可用 Presto 函数的列表:https://docs.aws.amazon.com/athena/latest/ug/presto-functions.html (3认同)
  • 确实,“any_match”在 Athena 中不可用 (2认同)

jen*_*ter 2

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

select * from test
CROSS JOIN UNNEST(foo.usages) AS t(i)
where i.usage is null
Run Code Online (Sandbox Code Playgroud)

因此,如果您只需要唯一的集合,则必须通过SELECT DISTINCT.

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