【问题标题】:Presto filter json arrayPresto过滤器json数组
【发布时间】:2021-04-29 22:06:28
【问题描述】:

如何在 Presto 中过滤 json 数组?

WITH dataset AS (
  SELECT * FROM (VALUES
    (JSON '{"turnovers": [{"purpose": "Bla Bla", "amount": 3, "tag": "E"}, 
                          {"purpose": "Blub", "amount": 3, "tag": "F"}]}'),
    (JSON '{"turnovers": [{"purpose": "Palim", "amount": 3, "tag": "E"}, 
                          {"purpose": "Palim Palim", "amount": 3, "tag": "E"}]}')
  ) AS t (snapshot)
)
SELECT 
    json_extract(snapshot, '$.turnovers')
FROM 
    dataset

我只想获得带有标签E 的营业额,而不是所有交易。在本例中,应排除标签为F 的一笔交易。

这可能吗?

我希望像这样使用某物,但这不起作用

WITH dataset AS (
  SELECT * FROM (VALUES
    (JSON '{"turnovers": [{"purpose": "Bla Bla", "amount": 3, "tag": "E"}, 
                          {"purpose": "Blub", "amount": 3, "tag": "F"}]}'),
    (JSON '{"turnovers": [{"purpose": "Palim", "amount": 3, "tag": "E"}, 
                          {"purpose": "Palim Palim", "amount": 3, "tag": "E"}]}')
  ) AS t (snapshot)
)
SELECT 
    filter(json_extract(snapshot, '$.turnovers'), x -> json_extract_scalar(x, '$.tag')='E')
FROM 
    dataset

【问题讨论】:

    标签: presto


    【解决方案1】:

    这对我有用。 ARRAY(MAP(VARCHAR, JSON)) 非常灵活,也允许在 json 数组中嵌套 json。

    WITH dataset AS (
      SELECT * FROM (VALUES
        (JSON '{"turnovers": [{"purpose": "Bla Bla", "amount": 3, "tag": "E"},
                              {"purpose": "Blub", "amount": 3, "tag": "F"}]}'),
        (JSON '{"turnovers": [{"purpose": "Palim", "amount": 3, "tag": "E"},
                              {"purpose": "Palim Palim", "amount": 3, "tag": "E"}]}')
      ) AS t (snapshot)
    )
    SELECT
        CAST(filter(CAST(json_extract(snapshot, '$.turnovers') AS ARRAY(MAP(VARCHAR, JSON))), x -> json_format(x['tag']) = '"E"') AS JSON)
    FROM
        dataset
    

    【讨论】:

    • 你可以尝试使用element_at(x, 'tag') -> x['tag'] 来美化它。至少它对我有用 =) 或者 x -> json_format(x['tag']) = '"E"' 可以是一个选项而不是演员。
    【解决方案2】:

    您可以尝试使用带有表达式 json_extract(snapshot, '$.turnovers[?(@.tag == "E")]') 的 json 路径,但如果它对您来说失败,就像对我一样 - 将数据转换为行数组并过滤这些数组:

    WITH dataset AS (
      SELECT * FROM (VALUES
        (JSON '{"turnovers": [{"purpose": "Bla Bla", "amount": 3, "tag": "E"},
                              {"purpose": "Blub", "amount": 3, "tag": "F"}]}'),
        (JSON '{"turnovers": [{"purpose": "Palim", "amount": 3, "tag": "E"},
                              {"purpose": "Palim Palim", "amount": 3, "tag": "E"}]}')
      ) AS t (snapshot)
    )
    SELECT
        filter(CAST(json_extract(snapshot, '$.turnovers') as ARRAY(ROW(purpose VARCHAR, amount INTEGER, tag VARCHAR))), x -> x.tag = 'E')
    FROM
        dataset
    

    如果需要,您可以选择在过滤后转换回 json。

    【讨论】:

    • 谢谢!不幸的是,这给了我Final query status: FAILED - Reason: INVALID_CAST_ARGUMENT: Cannot cast JSON to array(row(purpose varchar,amount integer,tag varchar))。我在雅典娜运行这个。
    • @PalimPalim 回答中的查询昨天在雅典娜对我来说效果很好。我稍后再检查。
    • @PalimPalim 查询在雅典娜对我来说效果很好。您是否针对真实数据执行它?可能是json结构不同?
    • 不,我按原样复制并直接在那里运行。也许我的 aws athena 版本比您的版本或类似版本旧,但我找到了一种对我有用的不同方式(有点丑陋)。在此处查看其他答案。
    • @PalimPalim 是的,我也试过了,as ARRAY(MAP(VARCHAR, VARCHAR))), x -> x['tag'] = 'E' 对我有用(虽然它把所有东西都变成了字符串)。
    猜你喜欢
    • 2021-01-04
    • 1970-01-01
    • 2019-12-13
    • 2011-09-14
    • 1970-01-01
    • 2017-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多