如何用Presto SQL按用户及交易项获取最新交易日期?
Presto SQL实现按用户获取各交易项最新交易日期
当然可以用Presto SQL实现这个需求,你想到的拆分map再聚合的思路是可行的,而且是Presto里处理这类map场景的常规方案,以下是具体实现:
完整SQL代码
SELECT userid, map_agg(item, max_transaction_date) AS transaction_dates FROM ( SELECT userid, entry.key AS item, MAX(entry.value) AS max_transaction_date FROM your_table_name, UNNEST(map_entries(transaction_dates)) AS t(entry) GROUP BY userid, entry.key ) AS grouped_items GROUP BY userid;
步骤解释
- 拆分map为行数据:使用
map_entries(transaction_dates)将每个用户的交易map转换为键值对数组,再通过UNNEST把数组展开成单独的行,这样每个交易项(比如LEGO、XBOX)和对应的日期就变成一行数据。 - 分组取最新日期:按
userid和交易项分组,用MAX(entry.value)获取每个用户下每个交易项的最新日期(ISO格式的日期字符串可以直接用MAX比较大小)。 - 重新聚合为map:再次按
userid分组,用map_agg函数把每个用户的交易项和对应最新日期重新聚合成map类型的列,得到你需要的结果。
验证示例
针对你提供的输入数据:
| userid | transaction_dates |
|---|---|
| A | {'LEGO': '2022-05-03', 'XBOX': '2023-01-02'} |
| A | {'LEGO': '2022-06-01', 'PS': '2023-04-01', 'XBOX': '2022-01-01'} |
| B | {'SWITCH': '2021-05-01', 'APPLE': '2023-05-01'} |
执行上述SQL后会得到期望结果:
| userid | transaction_dates |
|---|---|
| A | {'LEGO': '2022-06-01', 'XBOX': '2023-01-02', 'PS': '2023-04-01'} |
| B | {'SWITCH': '2021-05-01', 'APPLE': '2023-05-01'} |
补充说明
Presto目前确实没有类似map_union_sum这种直接针对map值取最大值的聚合函数,但这种拆分-聚合的方式逻辑清晰,在大多数场景下性能表现足够。如果你的数据量极大,可以考虑提前对map列做预拆分优化,但常规业务场景下上述方案完全适用。
内容的提问来源于stack exchange,提问作者user98235
相关产品推荐
相关产品推荐

