【问题标题】:How to perform multiple array unnest() in parallel in Presto如何在 Presto 中并行执行多个数组 unnest()
【发布时间】:2020-04-21 09:06:19
【问题描述】:

我有以下这种格式的表格

create table raw_data (

userid BIGINT,
city  VARCHAR,
campaign ARRAY <
       STRUCT <campaignid BIGINT,
               campaign_start_at TIMESTAMP,
               campaign_ends_at TIMESTAMP,
               parameters ARRAY<
                           STRUCT < goal VARCHAR,
                                    reward VARCHAR
                                  >
               campaignstatus ARRAY
                          STRUCT < seen BOOLEAN ,
                                   seen_at TIMESTAMP
                                   action VARCHAR,
                                   action_at TIMESTAMP
                                  >
                                >
                 >)

我希望最终的结果是这样的:

userid|city|campaignid|campaign_start_at|campaign_ends_at|goal|reward|seen|seen_at|action|action_at

1 | Athens | 234   | 2019-03-19 12:00 |2019-03-19 14:00| 10| 2.7 | yes |2019-03-19 10:23|null|null
1 | Athens | 234   | 2019-03-19 12:00 |2019-03-19 14:00| 10| 2.7 | yes |2019-03-17 10:23|participate|2019-03-19 11:20
2 | Athens | 234   | 2019-03-19 12:00 |2019-03-19 14:00| 10| 2.7 | yes |2019-03-19 10:23|ignore|2019-03-19 10:10
3 | Athens | 234   | 2019-03-19 12:00 |2019-03-19 14:00| 10| 2.7 | null|null|null|null
3 | Athens | 234   | 2019-03-19 12:00 |2019-03-19 14:00| 10| 2.7 | yes |2019-03-19 12:23|blocked|2019-03-19 12:24

换句话说,我想取消嵌套数据并查找有关用户 ID 级别的信息。 我尝试使用以下脚本取消嵌套表

select * 
FROM raw_data 
LEFT JOIN UNNEST(campaign) as t(campaigns)

但它返回错误:表 hive.default.campaign 不存在

我的问题是:

是否可以在 presto 中并行取消嵌套多个数组?

  • 如果是,我该怎么做?
  • 如果不是,我应该按照什么顺序来取消嵌套更高级别(用户 ID)中的列,例如:由内向外或反之亦然?一个例子将不胜感激。

【问题讨论】:

  • "Table hive.default.campaign 不存在" -- 这听起来不像是一条正确的消息,但events 表中是否有 campaign 列?
  • 另外,您打算生成parameterscampaignstatus 的笛卡尔积还是“压缩”它们?
  • 嘿@PiotrFindeisen!首先,events 表命名错误 - 已更正。它应该是表 raw_data (是的,raw_data 有一个活动列)对于你的第二个问题,我想要一个笛卡尔积 campaignsparameterscampaignstatus。我希望所有这三个数组都链接到 uderid。例如:userid = 1 有两条相同活动 id (234) 的记录,一条记录是从用户那里看到的,但他没有采取任何行动,但当用户第二次看到他参与的活动时。不知道上面说的有没有道理?
  • 仅供参考:返回的错误是语法错误。

标签: presto


【解决方案1】:

所以基本上我找到了一个解决方案,相当简单但它有效。

为了取消嵌套所有嵌套数组,您需要从外部数组到内部数组。对于这个例子

  • 首先根据用户 ID 取消嵌套 campaign 数组
  • 其次根据用户 ID 和活动 ID 取消嵌套 campaignstatus 数组
  • 第三次取消嵌套parameters 数组。重要提示:parameters 数组可以作为对象(而不是数组)进行操作,因为所有数据都是字符串并且可以使用 json 函数访问。

更具体地说,查询将是这样的:

select 
   a.userid
   ,a.city
   ,a.campaignid 
   ,a.campaign_start_at 
   ,a.campaign_ends_at TIMESTAMP
   ,cs.sseen
   ,cs.seen_at
   ,cs.action
   ,cs.action_at
   ,json_array_get(cast(parameters as json),0) goal
   ,json_array_get(cast(parameters as json),1) reward

from (
       select
       userid
      ,city
      ,campaignid 
      ,campaign_start_at 
      ,campaign_ends_at TIMESTAMP

      from raw_data
      cross join unnest(campaign) as c
   ) a

cross join unnest(campaignstatus) as cs

不过,我希望阅读更复杂的解决方案。

【讨论】:

  • 注意:你不需要子查询(FROM (SELECT ...),你可以多次CROSS JOIN UNNEST (...) CROSS JOIN UNNEST (...)
  • 注意:您可能希望使用LEFT JOIN UNNEST .. ON true 而不是CROSS JOIN - 这样您就不会在未嵌套的数组之一为空时丢失行。 (为此,您需要一个相当新的 Presto 版本。如果您当前的版本不支持 LEFT JOIN UNNEST,请从 prestosql.io/download.html 获取 Presto 327)
  • 非常感谢@PiotrFindeisen。将尝试这两个建议!
  • 顺便说一句,如果您对 Presto 有任何不符合 SO 公式的问题,我邀请您到 Presto community slack
  • 很高兴知道!感谢您提及!
猜你喜欢
  • 2020-10-21
  • 2016-04-02
  • 1970-01-01
  • 2021-07-10
  • 1970-01-01
  • 2020-12-24
  • 2017-08-16
  • 1970-01-01
  • 2020-11-02
相关资源
最近更新 更多