在 Athena 中,我如何查询结构中数组中的结构成员?
In Athena how do I query a member of a struct in an array in a struct?
我正在尝试找出如何查询我正在检查 usage
的值的位置,给出以下 table 创建:
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: line 1:53: Expression "foo"."usages" is not of type ROW
如果我在直接索引数组的位置进行查询,如下所示,它会起作用。
SELECT * FROM "foo"."test" WHERE foo.usages[1].usage is null;
不过,我的总体目标是查询 usages
数组中的所有项目,并找到任何行,其中 usages
数组中至少有一个项目具有成员 usage
空。
您可以通过将数组取消嵌套成行然后检查这些行的 null
值来实现此目的。这将导致每个 null
值条目一行。
select * from test
CROSS JOIN UNNEST(foo.usages) AS t(i)
where i.usage is null
因此,如果您只需要唯一集,则必须 运行 通过 select 不同。
select distinct id from test
CROSS JOIN UNNEST(foo.usages) AS t(i)
where i.usage is null
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(<array>, <function>)
的方法是 cardinality(filter(<array>, <function>)) > 0
.
SELECT * FROM "foo"."test"
WHERE any_match(foo.usages, element -> element.usage IS NULL);
变为:
SELECT * FROM "foo"."test"
WHERE cardinality(filter(foo.usages, element -> element.usage IS NULL)) > 0
我正在尝试找出如何查询我正在检查 usage
的值的位置,给出以下 table 创建:
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: line 1:53: Expression "foo"."usages" is not of type ROW
如果我在直接索引数组的位置进行查询,如下所示,它会起作用。
SELECT * FROM "foo"."test" WHERE foo.usages[1].usage is null;
不过,我的总体目标是查询 usages
数组中的所有项目,并找到任何行,其中 usages
数组中至少有一个项目具有成员 usage
空。
您可以通过将数组取消嵌套成行然后检查这些行的 null
值来实现此目的。这将导致每个 null
值条目一行。
select * from test
CROSS JOIN UNNEST(foo.usages) AS t(i)
where i.usage is null
因此,如果您只需要唯一集,则必须 运行 通过 select 不同。
select distinct id from test
CROSS JOIN UNNEST(foo.usages) AS t(i)
where i.usage is null
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(<array>, <function>)
的方法是 cardinality(filter(<array>, <function>)) > 0
.
SELECT * FROM "foo"."test"
WHERE any_match(foo.usages, element -> element.usage IS NULL);
变为:
SELECT * FROM "foo"."test"
WHERE cardinality(filter(foo.usages, element -> element.usage IS NULL)) > 0