在尝试创建以下表格的情况下,我试图弄清楚如何查询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”。“用法”的类型不是ROW
如果我在查询中直接对数组进行索引,如下所示,那么它将起作用。
SELECT * FROM "foo"."test" WHERE foo.usages[1].usage is null;
尽管,我的总体目标是查询usages
数组中的所有项目,并找到usages
数组中至少一项具有成员usage
为空的行。
答案 0 :(得分:2)
雅典娜基于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)
答案 1 :(得分:1)
您可以通过将数组取消嵌套成行,然后检查其中的null
值来实现。这将导致每个null
值条目一行。
select * from test
CROSS JOIN UNNEST(foo.usages) AS t(i)
where i.usage is null
因此,如果您仅需要唯一的集合,则必须通过选择不同的集合来运行它。
select distinct id from test
CROSS JOIN UNNEST(foo.usages) AS t(i)
where i.usage is null